Java中的IO-04

回顾

之前已经介绍过很多的IO流了。比如四大抽象流InputStreamOutputStreamReader,Writer。前面的两个是字节流,后面的两个是字符流。所谓的字节流与字符流之间的最大的区别就是,字节流是写给计算机看的,而字符流写写给我们人看的。Java当中所有的IO流基本上都继承于这个四大抽象流,而且基本上都以他们结尾。之前还说过一个特殊的流OutputStreamWriterInputStreamReader。这两个流却是有点儿特殊,他们的前面是字节流,后面却是字符流。之前我们说他是处理字符相关的流,不过实际上他是将字节流转换成字符流的特殊流。因而我们可以指定编码(字节流转换成为字符流的一种方式)来进行字节到字符的转换。如果我们要处理一些字符文件的话,之前学的FileReaderFileWriter无疑是一个最合适的选择。如果要是处理一些字节文件比如图片或者视频什么的,我们需要使用字节流FileInputStreamFileOutputStream。不过单独使用这些流的话,效率可能是一个问题。所以缓冲区是必须的,Java IO 中给我们提供了缓冲的包装流BufferedInputStream,BufferedOutputStream,BufferedReader,BufferedWriter。这四个流是对前面的四个基本的抽象流的包装,如果不是什么特殊情况的话,我们可以每次都加上这个缓冲层。

ByteArrayInputStream, ByteArrayOutputStream

字节流我们只是介绍了一种,也就是从文件中读取字节。不过并不是所有的情况下我们都要从文件中读取字节的。比如说我们获取一个字节数组,我们想使用流来处理一下这个字节数组,好像我们现在学过的流中没有这样的功能。

于是现在我们引入了处理数组的新的流,ByteArrayInputStreamByteArrayOutputStream

下面就是我们正常的官方文档的学习环节。

java.lang.Object 
    java.io.InputStream 
        java.io.ByteArrayInputStream 
public class ByteArrayInputStream
extends InputStream
  • A ByteArrayInputStream包含一个内部缓冲区,其中包含可以从流中读取的字节。内部计数器跟踪read方法要提供的下一个字节。
  • 关闭ByteArrayInputStream没有任何效果。 在关闭流之后,可以调用此类中的方法,而不生成IOException
ByteArrayInputStream(byte[] buf) 
// 创建一个 ByteArrayInputStream ,使其使用 buf作为其缓冲区数组。  
ByteArrayInputStream(byte[] buf, int offset, int length) 
// 创建 ByteArrayInputStream使用 buf作为其缓冲器阵列。  
int available() 
// 返回可从此输入流读取(或跳过)的剩余字节数。  
void close() 
// 关闭 ByteArrayInputStream没有任何效果。  
void mark(int readAheadLimit) 
// 设置流中当前标记的位置。  
boolean markSupported() 
// 测试 InputStream是否支持标记/复位。  
int read() 
// 从该输入流读取下一个数据字节。  
int read(byte[] b, int off, int len) 
// 将 len字节的数据读入此输入流中的字节数组。  
void reset() 
// 将缓冲区重置为标记位置。  
long skip(long n) 
// 从此输入流跳过 n个字节的输入。  

其实上面的这些方法,和这些属性都是可以一眼就看懂的,和其他的流是没什么区别的。

看一下官方文档的第一点,我们可以知道使用ByteArrayInputStream内部有一个缓冲区,那是否可以使用BufferedInputStream来包装呢?这个肯定是可以用的,毕竟这个也是InputStream的子类吖。

第二点是关于这个流的关闭的,官方文档告诉我们,这个流的关闭是不会做任何事情的,也就是说我们可以选择不关闭。但是为了IO流中操作的有机的统一和规范。虽然关闭没有用,我们还是推荐来关闭一下子的。

代码举例

public class ByteArrayInputStreamDemo {
    public static void main(String[] args) {
        byte[] b = "sher is a wonderful boy!".getBytes();
        ByteArrayInputStream bais = new ByteArrayInputStream(b);
        StringBuilder sb = new StringBuilder();
        int temp = 0;
        while ((temp = bais.read()) != -1){
            sb.append((char) temp);
        }
        System.out.println(sb.toString());
    }
}

其实上面的我的用法不没有是把这个作为一个IO流来使用,所以也没有使用IO流的try catch finally的标准操作。而且这个流也是不会抛出IOException的。

下面随便写一个有关ByteArrayOutputStream的代码举例

public class ByteArrayOutputStreamDemo {
    public static void main(String[] args) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while (baos.size() <= 10){
            try {
                baos.write(System.in.read());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        byte[] b = baos.toByteArray();
        System.out.println(new String(b));

    }
}

这里也没有使用标准的IO流操作方式,毕竟这个流是有点儿特殊了。

CharArrayWriter, CharArrayReader

和上面的字节数组类似的,字符流中也有相应的流是和字符数组相关的。其实他们之间的道理是一样的,这里就不再赘述了。

public class CharArrayWriterDemo {
    public static void main(String[] args) {
        char[] ch = "sher is the best boy!".toCharArray();
        CharArrayWriter c = new CharArrayWriter();

        try {
            c.write(ch);
            c.flush();
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(c.toString());
    }
}
public class CharArrayReaderDemo {
    public static void main(String[] args) {
        char [] ch = "abcdefg".toCharArray();
        CharArrayReader char1 = new CharArrayReader(ch);
        StringBuilder sb = new StringBuilder();
        int temp = 0;
        while (true){
            try {
                if (((temp = char1.read()) == -1)) break;
            } catch (IOException e) {
                e.printStackTrace();
            }
            sb.append((char)temp);
        }
        System.out.println(sb.toString());
    }
}

总结

其实这些流都不是常见的流,基本上我们是用不到的。不过稍微做一下了解也是好的呢、


一枚小菜鸡