java流读写慢的根源是磁盘i/o瓶颈,优化需减少系统调用、降低上下文切换、避免零散操作;必须正确使用缓冲流:禁止单字节读、禁止循环新建、必须try-with-resources、按场景选合适缓冲区大小。

Java 中流读写慢,核心原因不是语言本身,而是没绕开磁盘 I/O 这个天然瓶颈。优化方向很明确:减少系统调用次数、降低上下文切换开销、避免小批量零散操作。缓冲流是第一道必选项,不是可选配置。
必须用对缓冲流,而不是“套一层”就完事
很多代码看似用了 BufferedInputStream,但实际性能没提升,问题出在用法上:
- 别在循环里反复 new 流对象——每次创建都重置缓冲区,初始化开销白费
- 务必用 try-with-resources,确保 close() 被调用,否则缓冲区里未刷出的数据会丢失
- 不要只调 bis.read() 单字节方法,它仍走底层单次读路径;一定要配合 byte[] 批量读,例如 byte[] buf = new byte[8192],再调 bis.read(buf)
- 处理文本时直接用 BufferedReader/Writer,它们自带缓冲且提供 readLine(),比手动拼接字符串高效得多
按场景选缓冲区大小,8KB 不是万能默认值
缓冲区太小,起不到聚合效果;太大,可能造成单次读写延迟升高,尤其在 HDD 上:
- 小文本(
- 日志归档、大文件复制(100MB+):建议 32KB–64KB,实测提速 15%–30%
- SSD 环境可试 128KB;HDD 则不建议超过 64KB
- BufferedInputStream 构造器第二个参数就是 size,单位字节,例如 new BufferedInputStream(fis, 32768)
超大文件或高吞吐场景,该切 NIO 就别硬扛
当缓冲流已到极限,或需精确控制内存与零拷贝时,NIO 是更底层的解法:
- 用 FileChannel + ByteBuffer 做顺序读写,避免 JVM 堆内存中转,降低 GC 压力
- 超大文本文件可考虑 Files.lines(Paths.get(...)),它内部做了资源管理和缓冲优化,适合函数式处理
- 需要追加写入时,FileOutputStream 构造传 true 启用 append 模式,省去定位文件末尾的 seek 开销
- 注意显式指定字符集,如 StandardCharsets.UTF_8,防止平台默认编码引发隐性转码损耗
顺手避开几个常见拖慢性能的坑
有些细节不显眼,但一踩就让前面所有优化失效:
- 别在 while 循环里 new String(byte[], "UTF-8")——每行都新建字符串,GC 压力陡增;考虑复用 StringBuilder 或直接操作 char 数组
- 避免用 FileInputStream + InputStreamReader 拆开写,容易漏设编码;优先用 FileReader(但记得它不带缓冲,必须包一层 BufferedReader)
- 二进制文件(图片、音视频)坚决用字节流,别强转字符流,否则乱码还慢
- 频繁读写小文件?考虑合并成批量操作,或改用内存映射 MappedByteBuffer(慎用于超大文件,有内存占用风险)
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











