Java BufferedInputStream 类
最后修改时间:2025 年 4 月 16 日
java.io.BufferedInputStream
类为另一个输入流添加缓冲功能。它通过减少本地 I/O 调用的数量来提高性能。数据从底层流以大块的形式读取到缓冲区中。
BufferedInputStream
封装另一个 InputStream
,并提供缓冲读取功能。默认缓冲区大小为 8192 字节 (8KB),但可以指定自定义大小。此类对于并发访问是线程安全的。
BufferedInputStream 类概述
BufferedInputStream
扩展 FilterInputStream
并提供缓冲输入操作。主要方法包括读取操作、mark/reset 功能和流跳过。当执行读取操作时,缓冲区会被填满。
public class BufferedInputStream extends FilterInputStream { public BufferedInputStream(InputStream in); public BufferedInputStream(InputStream in, int size); public synchronized int read(); public synchronized int read(byte[] b, int off, int len); public synchronized long skip(long n); public synchronized int available(); public synchronized void mark(int readlimit); public synchronized void reset(); public boolean markSupported(); public synchronized void close(); }
上面的代码展示了 BufferedInputStream
提供的关键方法。这些方法允许通过缓冲进行高效的数据读取。如果底层流支持它们,则该类支持 mark 和 reset 操作。
创建 BufferedInputStream
BufferedInputStream 通过将其封装在另一个 InputStream
中创建。您可以指定缓冲区大小或使用默认值。缓冲区大小会影响 I/O 性能 - 较大的缓冲区减少本地调用,但使用更多内存。
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; public class Main { public static void main(String[] args) { try { // Create with default buffer size InputStream fileStream = new FileInputStream("data.txt"); BufferedInputStream bufferedStream1 = new BufferedInputStream(fileStream); // Create with custom buffer size (16KB) InputStream fileStream2 = new FileInputStream("data.txt"); BufferedInputStream bufferedStream2 = new BufferedInputStream(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(); } } }
此示例演示了创建 BufferedInputStream 的不同方法。第一个使用默认缓冲区大小,第二个指定 16KB。完成后务必关闭流以释放资源。关闭 BufferedInputStream 时,底层 FileInputStream 会自动关闭。
使用 BufferedInputStream 读取数据
BufferedInputStream 提供了几种用于读取数据的方法。最简单的方法是读取单个字节。更有效的方法是将多个字节读入数组。所有读取操作都是同步的,以确保线程安全。
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.txt"))) { // Read single byte int byteData; while ((byteData = bis.read()) != -1) { System.out.print((char) byteData); } System.out.println("\n\nReading complete"); } catch (IOException e) { e.printStackTrace(); } } }
此示例展示了如何使用 BufferedInputStream
逐字节读取文件。try-with-resources 语句确保了流的正确关闭。read 方法在流的末尾返回 -1。每次调用 read
可能会从缓冲区而不是底层流中获取数据。
将字节读入数组
为了获得更好的性能,一次将多个字节读入一个字节数组。这减少了方法调用和本地 I/O 操作。read 方法返回实际读取的字节数。
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("largefile.dat"))) { byte[] buffer = new byte[1024]; int bytesRead; while ((bytesRead = bis.read(buffer)) != -1) { System.out.println("Read " + bytesRead + " bytes"); // Process the buffer data here } System.out.println("File reading complete"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了批量读取到字节数组中。可以根据性能需求调整缓冲区大小 (1024)。bytesRead 值指示实际读取到数组中的字节数。这可能小于文件末尾的数组长度。
Mark 和 Reset 功能
BufferedInputStream 支持 mark 和 reset 操作以重新读取数据。mark 方法标记当前位置,reset 返回到该位置。readlimit 参数指定在 mark 变为无效之前可以读取的字节数。
import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String data = "BufferedInputStream mark/reset example"; byte[] bytes = data.getBytes(); try (BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(bytes))) { // Read first 10 bytes byte[] firstPart = new byte[10]; bis.read(firstPart); System.out.println("First part: " + new String(firstPart)); // Mark current position bis.mark(20); // Allow 20 bytes to be read before mark invalid // Read next 10 bytes byte[] secondPart = new byte[10]; bis.read(secondPart); System.out.println("Second part: " + new String(secondPart)); // Reset back to mark bis.reset(); // Read again from marked position bis.read(secondPart); System.out.println("Second part after reset: " + new String(secondPart)); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了 mark 和 reset 功能。在读取前 10 个字节后设置 mark。在读取接下来的 10 个字节后,reset 返回到标记位置。readlimit 为 20 意味着在标记后读取超过 20 个字节将使标记无效。
跳过流中的字节
skip 方法允许跳过流中指定数量的字节。这比读取和丢弃数据更有效。实际跳过的字节数可能小于请求的字节数。
import java.io.BufferedInputStream; import java.io.ByteArrayInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { String data = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"; byte[] bytes = data.getBytes(); try (BufferedInputStream bis = new BufferedInputStream(new ByteArrayInputStream(bytes))) { System.out.println("Starting position: " + bis.available()); // Skip first 10 bytes long skipped = bis.skip(10); System.out.println("Skipped " + skipped + " bytes"); // Read next byte int nextByte = bis.read(); System.out.println("Next byte: " + (char) nextByte); // Skip beyond end of stream skipped = bis.skip(20); System.out.println("Skipped " + skipped + " bytes (end approached)"); System.out.println("Remaining bytes: " + bis.available()); } catch (IOException e) { e.printStackTrace(); } } }
此示例展示了如何在流中跳过字节。第一个 skip 跳过前 10 个字母。第二个 skip 尝试跳过 20 个字节,但只跳过剩余的字节。available 方法显示无需阻塞即可读取的字节数。
可用字节和性能
available 方法返回一个估计值,表示无需阻塞即可读取的字节数。BufferedInputStream 的实现同时考虑了缓冲区和底层流。这对于检查流状态很有用。
import java.io.BufferedInputStream; import java.io.FileInputStream; import java.io.IOException; public class Main { public static void main(String[] args) { try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream("data.bin"))) { System.out.println("Initially available: " + bis.available() + " bytes"); // Read some data byte[] buffer = new byte[100]; bis.read(buffer); System.out.println("After reading 100 bytes, available: " + bis.available() + " bytes"); // Fill buffer by reading more while (bis.available() > 0) { bis.read(buffer); System.out.println("Read 100 bytes, remaining: " + bis.available()); } System.out.println("Stream fully read"); } catch (IOException e) { e.printStackTrace(); } } }
此示例演示了使用 available
来监视流的读取进度。该方法返回缓冲区和底层流中剩余的总字节数。请注意,available
只是一个估计值,不应用于确定确切的剩余数据大小。
来源
在本文中,我们介绍了 Java BufferedInputStream 类的基本方法和特性。理解这些概念对于在 Java 应用程序中处理高效的 I/O 操作至关重要。
作者
列出所有Java教程。