Java BufferedOutputStream 类
最后修改时间:2025 年 4 月 16 日
java.io.BufferedOutputStream
类为另一个输出流添加缓冲功能。它通过减少本机 I/O 调用次数来提高性能。数据从缓冲区以大块形式写入底层流。
BufferedOutputStream
包装另一个 OutputStream
并提供缓冲写入功能。默认缓冲区大小为 8192 字节(8KB),但可以指定自定义大小。此类是线程安全的,可用于并发访问。
BufferedOutputStream 类概述
BufferedOutputStream
扩展了 FilterOutputStream
并提供了缓冲输出操作。关键方法包括写入操作和刷新功能。缓冲区在写入底层流之前会填充数据。
public class BufferedOutputStream extends FilterOutputStream { public BufferedOutputStream(OutputStream out); public BufferedOutputStream(OutputStream out, int size); public synchronized void write(int b); public synchronized void write(byte[] b, int off, int len); public synchronized void flush(); public void close(); }
上面的代码显示了 BufferedOutputStream
提供的关键方法。这些方法允许使用缓冲进行高效的数据写入。flush 方法确保所有缓冲数据都写入底层流。
创建 BufferedOutputStream
通过将 BufferedOutputStream 包装在另一个 OutputStream
周围来创建它。您可以指定缓冲区大小或使用默认值。缓冲区大小会影响 I/O 性能 - 较大的缓冲区减少本机调用,但会使用更多内存。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { try { // Create with default buffer size OutputStream fileStream = new FileOutputStream("output.txt"); BufferedOutputStream bufferedStream1 = new BufferedOutputStream(fileStream); // Create with custom buffer size (16KB) OutputStream fileStream2 = new FileOutputStream("output2.txt"); BufferedOutputStream bufferedStream2 = new BufferedOutputStream(fileStream2, 16384); System.out.println("Default buffer stream created"); System.out.println("Custom buffer (16KB) stream created"); bufferedStream1.close(); bufferedStream2.close(); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了创建 BufferedOutputStream 的不同方法。第一个使用默认缓冲区大小,而第二个指定 16KB。完成操作后始终关闭流以释放资源。关闭 BufferedOutputStream 时,会自动关闭底层 FileOutputStream。
使用 BufferedOutputStream 写入数据
BufferedOutputStream 提供了几种写入数据的方法。最简单的方法是写入单个字节。更有效的方法是从数组写入多个字节。所有写入操作都同步以确保线程安全。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("output.txt"))) { // Write single bytes bos.write('H'); bos.write('e'); bos.write('l'); bos.write('l'); bos.write('o'); // Flush to ensure data is written bos.flush(); System.out.println("Data written to file"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了如何使用 BufferedOutputStream
逐字节写入数据。try-with-resources 语句确保正确关闭流。flush 方法确保所有缓冲数据都立即写入底层流。
写入字节数组
为了获得更好的性能,请一次从字节数组写入多个字节。这减少了方法调用和本机 I/O 操作。缓冲区会自动处理大型写入的分块。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("data.bin"))) { byte[] data = {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08}; // Write entire array bos.write(data); // Write partial array (bytes 2-5) bos.write(data, 2, 4); System.out.println("Byte arrays written to file"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了写入完整和部分字节数组。第一个写入操作写入所有 8 个字节。第二个仅写入从索引 2 开始的 4 个字节。缓冲区会自动管理何时实际写入底层流。
刷新缓冲区
flush 方法强制将所有缓冲数据写入底层流。当需要及时写入时,这一点很重要。关闭流也会自动刷新缓冲区。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("log.txt"))) { // Write log entries bos.write("Starting application\n".getBytes()); // Important - ensure log entry is written immediately bos.flush(); // Simulate work for (int i = 0; i < 1000000; i++) { // Some processing } bos.write("Work completed\n".getBytes()); System.out.println("Log entries written with explicit flush"); } catch (IOException e) { e.printStackTrace(); } } }
此示例显示了刷新对于关键日志条目的重要性。第一个消息会立即刷新,以确保即使程序稍后崩溃也会写入。如果没有刷新,消息可能会保留在缓冲区中,直到缓冲区填满或流关闭。
性能比较
BufferedOutputStream 显着提高了小写入的性能。此示例比较了使用和不使用缓冲的写入。当有许多小写入时,差异变得明显。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; public class Main { public static void main(String[] args) { final int COUNT = 100000; // Unbuffered write long start = System.currentTimeMillis(); try (OutputStream os = new FileOutputStream("unbuffered.txt")) { for (int i = 0; i < COUNT; i++) { os.write(i % 256); } } catch (IOException e) { e.printStackTrace(); } long unbufferedTime = System.currentTimeMillis() - start; // Buffered write start = System.currentTimeMillis(); try (OutputStream os = new BufferedOutputStream( new FileOutputStream("buffered.txt"))) { for (int i = 0; i < COUNT; i++) { os.write(i % 256); } } catch (IOException e) { e.printStackTrace(); } long bufferedTime = System.currentTimeMillis() - start; System.out.println("Unbuffered time: " + unbufferedTime + " ms"); System.out.println("Buffered time: " + bufferedTime + " ms"); } }
此性能测试写入 100,000 个单独的字节,有和没有缓冲。缓冲版本通常更快,因为它最大限度地减少了本机 I/O 调用。确切的速度差异取决于系统和存储介质。
写入文本数据
虽然 BufferedOutputStream 处理字节,但它通常与文本数据一起使用,方法是将字符串转换为字节。此示例演示了高效的文本写入以及正确的字符编码处理。
import java.io.BufferedOutputStream; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; public class Main { public static void main(String[] args) { try (BufferedOutputStream bos = new BufferedOutputStream( new FileOutputStream("text.txt"))) { String header = "User Log\n========\n"; bos.write(header.getBytes(StandardCharsets.UTF_8)); for (int i = 1; i <= 10; i++) { String line = String.format("User %d logged in\n", i); bos.write(line.getBytes(StandardCharsets.UTF_8)); } System.out.println("Text file written with UTF-8 encoding"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了使用正确的 UTF-8 编码写入文本数据。每个字符串在写入之前都会转换为字节。缓冲使即使有许多小写入也能高效地进行。始终指定字符集以避免平台相关的默认设置。
来源
在本文中,我们介绍了 Java BufferedOutputStream 类的基本方法和特性。理解这些概念对于在 Java 应用程序中使用高效的 I/O 操作至关重要。
作者
列出所有Java教程。