跳转到内容
主菜单
主菜单
移至侧栏
隐藏
导航
首页
最近更改
随机页面
MediaWiki帮助
代码酷
搜索
搜索
中文(中国大陆)
外观
创建账号
登录
个人工具
创建账号
登录
未登录编辑者的页面
了解详情
贡献
讨论
编辑“︁
Java BufferedInputStream
”︁
页面
讨论
大陆简体
阅读
编辑
编辑源代码
查看历史
工具
工具
移至侧栏
隐藏
操作
阅读
编辑
编辑源代码
查看历史
常规
链入页面
相关更改
特殊页面
页面信息
外观
移至侧栏
隐藏
您的更改会在有权核准的用户核准后向读者展示。
警告:
您没有登录。如果您进行任何编辑,您的IP地址会公开展示。如果您
登录
或
创建账号
,您的编辑会以您的用户名署名,此外还有其他益处。
反垃圾检查。
不要
加入这个!
{{Note|本文适用于Java初学者及需要了解缓冲输入流的开发者。所有示例基于Java 8+环境。}} = Java BufferedInputStream = '''BufferedInputStream'''是Java I/O库中提供的一个带有缓冲功能的输入流类,通过减少底层系统的实际读取操作次数来提高I/O效率。它继承自`FilterInputStream`,属于装饰器模式(Decorator Pattern)的典型应用。 == 核心原理 == <mermaid> flowchart LR A[应用程序] -->|read| B(BufferedInputStream) B -->|批量读取| C[底层InputStream] C -->|填充缓冲区| B B -->|从缓冲区提供数据| A </mermaid> 数学上,设单次系统调用耗时为<math>t_{sys}</math>,缓冲区大小为<math>n</math>字节,则读取<math>m</math>字节数据的理论耗时从<math>m \cdot t_{sys}</math>降低至<math>\lceil m/n \rceil \cdot t_{sys}</math> == 构造函数 == 提供两种主要构造方式: <syntaxhighlight lang="java"> // 方式1:使用默认缓冲区大小(通常8192字节) InputStream fis = new FileInputStream("test.txt"); BufferedInputStream bis = new BufferedInputStream(fis); // 方式2:自定义缓冲区大小 BufferedInputStream bisCustom = new BufferedInputStream(fis, 16384); // 16KB缓冲区 </syntaxhighlight> == 核心方法 == {| class="wikitable" ! 方法 !! 描述 |- | `int read()` || 读取单个字节,返回-1表示EOF |- | `int read(byte[] b, int off, int len)` || 读取到字节数组的指定位置 |- | `long skip(long n)` || 跳过指定字节数 |- | `void mark(int readlimit)` || 设置标记点 |- | `void reset()` || 返回到标记点 |- | `boolean markSupported()` || 是否支持标记(BufferedInputStream返回true) |} == 性能对比示例 == 测试读取100MB文件的耗时差异: <syntaxhighlight lang="java"> public class PerformanceTest { static void readWithoutBuffer() throws IOException { try (InputStream is = new FileInputStream("largefile.bin")) { long start = System.nanoTime(); while (is.read() != -1); // 逐字节读取 System.out.printf("无缓冲耗时: %.2fms\n", (System.nanoTime()-start)/1e6); } } static void readWithBuffer() throws IOException { try (InputStream is = new BufferedInputStream(new FileInputStream("largefile.bin"))) { long start = System.nanoTime(); while (is.read() != -1); // 通过缓冲读取 System.out.printf("缓冲耗时: %.2fms\n", (System.nanoTime()-start)/1e6); } } } </syntaxhighlight> 典型输出结果: <pre> 无缓冲耗时: 4520.17ms 缓冲耗时: 320.45ms </pre> == 实际应用场景 == === 场景1:大文件逐行处理 === <syntaxhighlight lang="java"> try (BufferedReader br = new BufferedReader( new InputStreamReader( new BufferedInputStream( new FileInputStream("huge_log.txt"))))) { br.lines().forEach(line -> { // 处理每行日志 if(line.contains("ERROR")) { System.out.println("发现错误: " + line); } }); } </syntaxhighlight> === 场景2:网络资源下载 === <syntaxhighlight lang="java"> URL url = new URL("https://example.com/large.zip"); try (BufferedInputStream in = new BufferedInputStream(url.openStream()); FileOutputStream out = new FileOutputStream("local_copy.zip")) { byte[] buffer = new byte[8192]; int bytesRead; while ((bytesRead = in.read(buffer)) != -1) { out.write(buffer, 0, bytesRead); } } </syntaxhighlight> == 高级技巧 == === 缓冲区大小优化 === 缓冲区大小应考虑: * 文件平均大小(小文件适合较小缓冲区) * 可用内存(通常8KB-64KB为宜) * 存储介质特性(SSD可适当减小缓冲区) === 与NIO结合使用 === Java NIO的`ByteBuffer`可进一步提升性能: <syntaxhighlight lang="java"> try (FileChannel channel = FileChannel.open(Paths.get("data.bin"))) { ByteBuffer buffer = ByteBuffer.allocateDirect(8192); // 直接缓冲区 while (channel.read(buffer) != -1) { buffer.flip(); // 处理数据... buffer.clear(); } } </syntaxhighlight> == 常见问题 == '''Q: 为什么读取完数据后需要关闭流?'''<br> A: 关闭流会释放系统资源(如文件句柄),且会强制刷新缓冲区。使用try-with-resources可自动处理。 '''Q: 缓冲区大小是否越大越好?'''<br> A: 过大的缓冲区会导致:①内存浪费 ②延迟首次数据可用时间 ③可能触发GC '''Q: 如何复用缓冲区?'''<br> A: 可创建全局缓冲区池(高级用法): <syntaxhighlight lang="java"> class BufferPool { private static final ConcurrentLinkedQueue<byte[]> pool = new ConcurrentLinkedQueue<>(); static byte[] getBuffer(int size) { byte[] buf = pool.poll(); return buf != null && buf.length >= size ? buf : new byte[size]; } static void returnBuffer(byte[] buf) { if(buf != null) pool.offer(buf); } } </syntaxhighlight> == 最佳实践 == 1. 始终使用try-with-resources确保流关闭 2. 对敏感数据读取后清空缓冲区: <syntaxhighlight lang="java"> Arrays.fill(buffer, (byte)0); // 清除内存中的敏感数据 </syntaxhighlight> 3. 考虑使用`BufferedInputStream`包装所有`InputStream`实例(除非确定不需要缓冲) {{Warning|多线程环境下,`BufferedInputStream`实例不是线程安全的!需要外部同步或使用独立实例。}} [[Category:编程语言]] [[Category:Java]] [[Category:Java IO]]
摘要:
请注意,所有对代码酷的贡献均被视为依照知识共享署名-非商业性使用-相同方式共享发表(详情请见
代码酷:著作权
)。如果您不希望您的文字作品被随意编辑和分发传播,请不要在此提交。
您同时也向我们承诺,您提交的内容为您自己所创作,或是复制自公共领域或类似自由来源。
未经许可,请勿提交受著作权保护的作品!
取消
编辑帮助
(在新窗口中打开)
该页面使用的模板:
模板:Mbox
(
编辑
)
模板:Note
(
编辑
)
模板:Warning
(
编辑
)
模块:Arguments
(
编辑
)
模块:Message box
(
编辑
)
模块:Message box/ambox.css
(
编辑
)
模块:Message box/configuration
(
编辑
)
模块:Yesno
(
编辑
)