内存操作流

之前的所有的流操作都是针对文件的,但是有时候只是想要实现数据间转换,此时如果我们想要创建一个文件然后再删除文件,那样显得有点麻烦,因此此时的内存操作流就显得很适合这类的操作,因为它只是在内存中存储,并不会真正的创建文件,内存操作流涉及的两个类是ByteArrayInputStream,ByteArrayOutputStream.

ByteArrayInputStream

  • ByteArrayInputStream 包含一个内部缓冲区,该缓冲区包含从流中读取的字节。内部计数器跟踪 read 方法要提供的下一个字节。

  • 关闭 ByteArrayInputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

  • 主要的功能是从缓冲区读取字节

构造函数

  • ByteArrayInputStream(byte[] buf) 创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组。

  • ByteArrayInputStream(byte[] buf, int offset, int length) 创建 ByteArrayInputStream,使用 buf 作为其缓冲区数组。

常用的方法

  • close() 不过对这个无效,因为关闭之后仍然可以使用函数读取而不报错

  • int read() 从缓冲区中读取一个字节

  • int read(byte[] bytes) 将缓冲区中的内容读取到数组中

  • int read(byte[] bytes,int off,int len) 将最多 len 个数据字节从此输入流读入 byte 数组。

  • long skip(long n) 从此输入流中跳过 n 个输入字节。

  • void reset() 将此 byte 数组输出流的 count 字段重置为零,从而丢弃输出流中目前已累积的所有输出(清除缓冲区)

实例

public class demo8 {
    public static void main(String args[]) {
        String str = "chenjiabing\n陈加兵";
        byte[] bytes = str.getBytes();  //创建一个数组
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);  //使用bytes作为缓冲区数组
        int temp = 0;
        /*第一种方法读取缓冲区中的数据,这个和文件的操作不一样,这个可以直接冲缓冲区中读取数据字节*/
        while ((temp = inputStream.read()) != -1) {
            System.out.print((char) temp);
        }

        /*创建数组用于存储读取的内容,下面是第二种读取数据的方法*/
        byte[] b = new byte[bytes.length];
        try {
            int len = inputStream.read(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(new String(b));

    }

}

ByteArrayOutputStream

  • 此类实现了一个输出流,其中的数据被写入一个 byte 数组。缓冲区会随着数据的不断写入而自动增长。可使用 toByteArray() 和 toString() 获取数据。

  • 关闭 ByteArrayOutputStream 无效。此类中的方法在关闭此流后仍可被调用,而不会产生任何 IOException

构造函数

  • ByteArrayOutputStream() 创建一个新的 byte 数组输出流。

  • ByteArrayOutputStream(int size) 创建一个新的 byte 数组输出流,它具有指定大小的缓冲区容量(以字节为单位)。

常用函数

  • int size() 返回缓冲区的当前大小。

  • byte[] toByteArray() 创建一个新分配的 byte 数组。

  • String toString() 将缓冲区的字节转换成字符串

  • void write(byte[] b, int off, int len) 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte 数组输出流。

  • void write(int b) 将指定的字节写入此 byte 数组输出流。

实例

public class demo8 {
    public static void main(String args[]) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String str = "chenjiabing";
        try {
            outputStream.write(str.getBytes());   //将字符串转换成数组然后写入缓冲区
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                outputStream.close();  //这里的关闭无效
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        //将缓冲区的数据转换成字符串后输出,这里同样可以看出输出流的关闭根本不影响函数的调用
        System.out.println(outputStream.size());  //输出缓冲区的大小
        System.out.println(outputStream.toString());  //输出chenjiabing
        outputStream.reset();   //清除缓冲区的内容,如果不清零那么原先写入的数据还是存在的,但是此时我们已经不需要前面的数据了
        try {
            outputStream.write("陈加兵".getBytes());  //继续向缓冲区写入数据
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println(outputStream.size());  //这里的一个汉字占了三个字节
        System.out.println(outputStream.toString());//输出陈加兵


    }

}

综合

下面我们结合上面的两个类将字符串转换大小写

public class demo8 {
    public static void main(String args[]) {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        String str = "chenjiabing";
        ByteArrayInputStream inputStream = new ByteArrayInputStream(str.getBytes());  //实例化输入流
        int temp = 0;
        while ((temp = inputStream.read()) != -1)   //读取缓冲区的字节数据
        {
            char c = (char) temp;  //将整数转换成字符,ascii码的转换
            outputStream.write(Character.toUpperCase(c));  //转换成大写,然后写入输出流的缓冲区中
        }
        System.out.println(outputStream.toString());   //利用输出流输出转换后的字符串,即是去取出内存中的数据


    }

}

参考文章


码猿技术专栏
486 声望105 粉丝