(每日持续更新)jdk api之BufferedOutputStream基础、应用、实战

2024-01-03 12:56:49

1.7 BufferedOutputStream

BufferedOutputStream 是 Java 中 OutputStream 的缓冲流实现,用于提高写入输出流的性能。它提供了缓冲区,将数据缓存起来并一次性写入底层输出流,减少了对底层流的频繁写入操作。

以下是 BufferedOutputStream 的一些常用属性和方法:

属性:
  1. protected byte[] buf

    • 用于存储缓冲数据的字节数组。可以通过构造函数指定缓冲区大小,也可以通过 getBuf() 方法获取。

  2. protected int count

    • 缓冲区中当前有效数据的字节数。

  3. protected OutputStream out

    • 内部原始的输出流。可以通过构造函数传入或通过 getOut() 方法获取。

构造函数:
  1. BufferedOutputStream(OutputStream out)

    • 使用默认缓冲区大小创建 BufferedOutputStream 对象。

  2. BufferedOutputStream(OutputStream out, int size)

    • 使用指定缓冲区大小创建 BufferedOutputStream 对象。

方法:
  1. void flush()

    • 刷新缓冲区,将缓冲区中的数据一次性写入底层输出流。

  2. void write(int b)

    • 将指定的字节写入缓冲区。

  3. void write(byte[] b, int off, int len)

    • 将字节数组中从偏移量 off 开始的 len 个字节写入缓冲区。

  4. void close()

    • 关闭输出流及其底层流。在关闭之前,会调用 flush 方法来确保所有缓冲数据都被写入底层流。

使用示例:
javaCopy code
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
?
public class BufferedOutputStreamExample {
?
 ?  public static void main(String[] args) {
 ? ? ?  String outputFilePath = "output.txt";
?
 ? ? ?  try (OutputStream fileOutputStream = new FileOutputStream(outputFilePath);
 ? ? ? ? ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream)) {
?
 ? ? ? ? ?  String data = "Hello, BufferedOutputStream!";
 ? ? ? ? ?  byte[] bytes = data.getBytes();
?
 ? ? ? ? ?  // 将字节数组写入缓冲区
 ? ? ? ? ?  bufferedOutputStream.write(bytes);
?
 ? ? ? ? ?  // 刷新缓冲区,将数据写入底层输出流
 ? ? ? ? ?  bufferedOutputStream.flush();
?
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ?  e.printStackTrace();
 ? ? ?  }
 ?  }
}

在这个例子中,BufferedOutputStream 被用来包装一个 FileOutputStream,以提供缓冲功能。通过 write 方法将字节数组写入缓冲区,通过 flush 方法将数据一次性写入文件。在实际应用中,使用缓冲流可以提高写入文件的性能,减少与底层输出流的直接交互次数。

应用场景

BufferedOutputStream 主要用于提高写入输出流的性能,特别是对于频繁写入小量数据的场景。以下是一些适合使用 BufferedOutputStream 的应用场景:

  1. 文件写入:

    • 当向文件中写入数据时,使用 BufferedOutputStream 可以减少对磁盘的频繁写入操作,提高写入效率。

    javaCopy code
    try (OutputStream fileOutputStream = new FileOutputStream("example.txt");
     ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream)) {
     ?  // 使用 bufferedOutputStream 写入文件数据
    } catch (IOException e) {
     ?  e.printStackTrace();
    }
  2. 网络数据传输:

    • 在向网络连接中写入数据时,使用 BufferedOutputStream 可以减少网络 I/O 操作,提高写入性能。

    javaCopy code
    try (Socket socket = new Socket("example.com", 80);
     ? ? OutputStream socketOutputStream = socket.getOutputStream();
     ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(socketOutputStream)) {
     ?  // 使用 bufferedOutputStream 写入网络数据
    } catch (IOException e) {
     ?  e.printStackTrace();
    }
  3. 数据流的写入:

    • 在处理数据流时,使用 BufferedOutputStream 可以减少对底层数据源的直接写入,提高写入性能。

    javaCopy code
    try (OutputStream outputStream = getSomeOutputStream();
     ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream)) {
     ?  // 使用 bufferedOutputStream 写入数据流
    } catch (IOException e) {
     ?  e.printStackTrace();
    }
  4. 日志记录:

    • 在记录大量日志数据时,使用 BufferedOutputStream 可以将日志信息缓存起来,并一次性写入日志文件,提高写入性能。

    javaCopy code
    try (OutputStream fileOutputStream = new FileOutputStream("application.log", true);
     ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream)) {
     ?  // 使用 bufferedOutputStream 写入日志信息
    } catch (IOException e) {
     ?  e.printStackTrace();
    }

总体而言,当需要频繁写入数据时,尤其是写入小量数据时,使用 BufferedOutputStream 可以减少 I/O 操作的次数,提高写入性能。在实际应用中,可以根据具体的场景和性能需求选择是否使用缓冲流。

实战例子

在一个真实项目中,使用 BufferedOutputStreamDataOutputStream 的场景可能涉及更为复杂的业务逻辑和数据模型。以下是一个简化的例子,模拟一个学生管理系统,将学生信息保存到二进制文件中。

学生类:

javaCopy code
import java.io.Serializable;
?
public class Student implements Serializable {
 ?  private static final long serialVersionUID = 1L;
?
 ?  private String name;
 ?  private int age;
 ?  private double score;
?
 ?  public Student(String name, int age, double score) {
 ? ? ?  this.name = name;
 ? ? ?  this.age = age;
 ? ? ?  this.score = score;
 ?  }
?
 ?  @Override
 ?  public String toString() {
 ? ? ?  return "Student{" +
 ? ? ? ? ? ? ?  "name='" + name + '\'' +
 ? ? ? ? ? ? ?  ", age=" + age +
 ? ? ? ? ? ? ?  ", score=" + score +
 ? ? ? ? ? ? ?  '}';
 ?  }
?
 ?  // 省略 getter 和 setter 方法
}

学生管理系统:

javaCopy code
import java.io.*;
import java.util.ArrayList;
import java.util.List;
?
public class StudentManagementSystem {
?
 ?  private static final String FILE_PATH = "students.dat";
?
 ?  public static void main(String[] args) {
 ? ? ?  List<Student> students = new ArrayList<>();
 ? ? ?  students.add(new Student("Alice", 20, 90.5));
 ? ? ?  students.add(new Student("Bob", 22, 85.0));
 ? ? ?  students.add(new Student("Charlie", 21, 92.3));
?
 ? ? ?  // 写入学生信息到文件
 ? ? ?  saveStudentsToFile(students);
?
 ? ? ?  // 从文件中读取学生信息
 ? ? ?  List<Student> loadedStudents = loadStudentsFromFile();
 ? ? ?  for (Student student : loadedStudents) {
 ? ? ? ? ?  System.out.println(student);
 ? ? ?  }
 ?  }
?
 ?  private static void saveStudentsToFile(List<Student> students) {
 ? ? ?  try (FileOutputStream fileOutputStream = new FileOutputStream(FILE_PATH);
 ? ? ? ? ? ? BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(fileOutputStream);
 ? ? ? ? ? ? DataOutputStream dataOutputStream = new DataOutputStream(bufferedOutputStream)) {
?
 ? ? ? ? ?  for (Student student : students) {
 ? ? ? ? ? ? ?  // 使用 DataOutputStream 提供的写入方法
 ? ? ? ? ? ? ?  dataOutputStream.writeUTF(student.getName());
 ? ? ? ? ? ? ?  dataOutputStream.writeInt(student.getAge());
 ? ? ? ? ? ? ?  dataOutputStream.writeDouble(student.getScore());
 ? ? ? ? ?  }
?
 ? ? ? ? ?  System.out.println("Students saved to file successfully.");
?
 ? ? ?  } catch (IOException e) {
 ? ? ? ? ?  e.printStackTrace();
 ? ? ?  }
 ?  }
?
 ?  private static List<Student> loadStudentsFromFile() {
 ? ? ?  List<Student> students = new ArrayList<>();
?
 ? ? ?  try (FileInputStream fileInputStream = new FileInputStream(FILE_PATH);
 ? ? ? ? ? ? BufferedInputStream bufferedInputStream = new BufferedInputStream(fileInputStream);
 ? ? ? ? ? ? DataInputStream dataInputStream = new DataInputStream(bufferedInputStream)) {
?
 ? ? ? ? ?  while (dataInputStream.available() > 0) {
 ? ? ? ? ? ? ?  // 使用 DataInputStream 提供的读取方法
 ? ? ? ? ? ? ?  String name = dataInputStream.readUTF();
 ? ? ? ? ? ? ?  int age = dataInputStream.readInt();
 ? ? ? ? ? ? ?  double score = dataInputStream.readDouble();
?
 ? ? ? ? ? ? ?  students.add(new Student(name, age, score));
 ? ? ? ? ?  }
?
 ? ? ? ? ?  System.out.println("Students loaded from file successfully.");
?
 ? ? ?  } catch (IOException | ClassNotFoundException e) {
 ? ? ? ? ?  e.printStackTrace();
 ? ? ?  }
?
 ? ? ?  return students;
 ?  }
}

在这个例子中,Student 类表示学生信息,实现了 Serializable 接口,以便对象的序列化和反序列化。StudentManagementSystem 类模拟了一个学生管理系统,通过 saveStudentsToFile 方法将学生信息保存到二进制文件,然后通过 loadStudentsFromFile 方法从文件中读取学生信息。

请注意,这只是一个简单的例子,实际的项目中可能会涉及更复杂的业务逻辑、错误处理、安全性考虑等。

文章来源:https://blog.csdn.net/a89879193/article/details/135322435
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。