Java 输入输出相关概念介绍(File、IO 流)(八)

195 阅读3分钟

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天,点击查看活动详情

这一系列文章主要是想把Java IO 相关的、可能会接触到的、常用的知识做一个整体的讲解。上一篇文章Java 输入输出相关概念介绍(File、IO 流)(七) 讲了两个OutputStream 抽象类的实现类,那两个实现类是我们日常开发中使用到最多的。这篇文章会延续上一篇文章的路径,继续介绍OutputStream 的两常用的实现类及使用方法。

BufferedOutputStream

这个类的含义是“缓存字节输出流”。

它有两个可以使用的构造方法

public BufferedOutputStream(OutputStream out)
public BufferedOutputStream(OutputStream out,int size)

size 参数的作用就是生命这个类中用于缓存的byte 数组的大小。

即,当我们创建BufferedOutputStream 时,会创建一个内部缓冲区数组(是个byte 数组),应用程序可以向这里写入字节数据。当写入数据时,可以不用每次都去调用底层方法,而是直接从缓存区获取数据。

直到缓冲区满了,或者我们调用close 方法关闭输出流,再或者调用flush 方法,缓冲区的数据才会写入目标中去(从内存中转移到磁盘上),因此效率是非常高的,避免了频繁的交互。

使用举例

public static void main(String[] args) throws IOException {
  FileOutputStream fileOutputStream = new FileOutputStream("copy.txt");
  BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
  byte[] buffer = new String("1234567qwertasdfzcxv").getBytes();
  bufferedOutputStream.write(buffer);
  // 调用这个函数的关闭的时候,会把缓存中的数据刷入到文件中去
  bufferedOutputStream.close();
  fileOutputStream.close();
}

在我们读取文件的时候,有时候可能面临着文件过于庞大,如果想一次性读取,那么内存可能装不下。但是如果一个一个字节地读取,那会耗费大量的资源和时间。

接下来我们直接举个例子,使用BufferedInputStream 和BufferedOutputStream 配合,对大文件进行分批读取。

public static void main(String[] args) throws IOException {
  try (FileInputStream fileInputStream = new FileInputStream(new File("copy.txt"));
       BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
       // 输出缓冲流
       OutputStream output = new FileOutputStream(new File("to_copy.txt"));
       BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(output);) {

    // 定义缓冲字节数组
    byte[] bytes = new byte[1024];
    int len = 0;
    while ((len = bufferedInputStream.read(bytes)) != -1) {
      bufferedOutputStream.write(bytes, 0, len);
    }
  } catch (IOException e) {
      // todo
  }
}

ObjectOutputStream

这个类是对象字节输出流,与它配合的是ObjectInputStream,它们统称对象操作流

它常用的构造方法如下:

public ObjectOutputStream (OutputStream out)

作用是将某个序列化的对象持久化输出,比如说保存到硬盘中。

public static void main(String[] args) throws IOException {
    TestObject to1 = new TestObject("abc", 123);
    TestObject to2 = new TestObject("def", 456);
    ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("copy.txt"));
    objectOutputStream.writeObject(to1);
    objectOutputStream.writeObject(to2);
    objectOutputStream.close();
}

这样两个对象s1 和s2 序列化后的数据就被保存到了copy.txt 文件中。

在读取的时候,我们需要使用到ObjectInputStream(对象字节输入流),代码示例如下:

public static void main(String[] args) throws IOException, ClassNotFoundException {
    ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("copy.txt"));
    TestObject to1 = (TestObject) objectInputStream.readObject();
    TestObject to2 = (TestObject) objectInputStream.readObject();
    System.out.println(to1);
    System.out.println(to2);
    objectInputStream.close();
}

总结

这次主要讲解了BufferedOutputStreamBufferedOutputStream 两个类的使用方法。

每次不多讲解,少而精地讲解一些类的基本概念和使用方法。之后的文章会继续介绍另外几个OutputStream 的不常用的实现类的用法。