安全处理超大二进制文件需流式分块读写:用 fileinputstream/bufferedinputstream 按固定大小(如64kb)读取,避免 readallbytes;边读边处理边写入 bufferedoutputstream;性能敏感时可用 filechannel + allocatedirect;所有资源必须 try-with-resources 及时释放。

处理超大二进制文件时,内存溢出(OOM)几乎都源于“一次性加载”——比如用 Files.readAllBytes() 或把整个文件塞进 ByteArrayOutputStream。真正安全的做法是:让数据以可控块状“流”进来、“流”出去,内存中只留当前这一块。
用固定大小字节块读取,不依赖换行符
二进制文件没有自然行边界,不能靠 readLine()。必须按字节块(如 8KB–1MB)拉取:
- 推荐使用
FileInputStream+BufferedInputStream,显式指定缓冲区大小(例如new byte[64 * 1024]) - 每次调用
read(byte[] b)返回实际读取字节数,需判断是否为 -1(EOF)或小于数组长度(最后一块) - 避免用
readAllBytes()、readAllLines()等全量方法——它们会把整个文件拷进堆内存
边读边写,不累积中间结果
除非业务强依赖全部数据(如校验、加密),否则不要把所有块缓存在 List 或 ByteArrayOutputStream 中:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- 读一块 → 处理一块(解密/解析/校验)→ 写一块到目标文件或输出流
- 写入时也用
BufferedOutputStream,同样设合理缓冲(如 32KB),减少系统调用次数 - 若需暂存处理结果(如转码后写入新文件),直接
write()到FileOutputStream,而非先 collect 到内存再 dump
用 NIO 的 ByteBuffer 配合 FileChannel 提升效率
对性能敏感或文件极大(>1GB),可考虑 NIO 方式,更贴近操作系统 I/O 调度:
- 用
FileChannel.open(path, READ)打开通道,分配直接内存缓冲(ByteBuffer.allocateDirect(1024 * 1024)) - 循环
channel.read(buffer),每次buffer.flip()后处理,再buffer.clear()复用 - 注意:直接内存不受 GC 管理,但不会导致堆 OOM;需确保 buffer 不被长期持有,避免堆外内存泄漏
资源必须及时释放,且避免长生命周期引用
哪怕用了流式读写,若流没关、对象没置 null,仍可能因引用滞留引发 OOM:
- 所有流(InputStream/OutputStream/Channel)必须放在 try-with-resources 中,或手动
close() - 处理过程中生成的临时对象(如解析后的 DTO 列表),处理完立即丢弃,不存入静态集合或 long-lived 缓存
- 若用线程池并发读多个分片,每个任务返回的是原始字节数组或处理结果,不要返回未关闭的流或 channel
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










