Java合并小文件为大二进制文件的核心是顺序字节拼接:用FileInputStream+FileOutputStream或Files.copy()配合SeekableByteChannel,缓冲读取、避免编码转换与额外分隔符,确保纯二进制追加。

Java 中将多份小文件合并为一个大型二进制文件,核心是按顺序读取每个源文件的原始字节,并写入到一个目标输出流中——不解析内容、不换行、不添加分隔符,保持纯粹的二进制拼接。
使用 FileInputStream + FileOutputStream(适合中小文件)
这是最直接、内存可控的方式。逐个打开小文件,用缓冲数组读取并写入目标文件,避免一次性加载全部内容到内存。
- 创建 FileOutputStream 指向最终的大文件(注意:不要用
new FileOutputStream(file, true)追加模式来拼接多个流,应统一由一个输出流管理) - 对每个小文件,新建 FileInputStream,用
byte[8192]等缓冲区循环read()→write() - 每次读取后检查返回值(
-1表示结束),确保完整写入 - 用 try-with-resources 自动关闭每个流,防止句柄泄漏
使用 Files.copy() + SeekableByteChannel(更简洁,JDK 7+)
借助 NIO 的 Files.copy() 可以简化复制逻辑,配合 SeekableByteChannel 控制写入位置,适合需要精确控制偏移或后续随机访问的场景。
- 用
FileChannel.open(Paths.get("big.bin"), WRITE, CREATE)打开可写通道 - 对每个小文件,调用
Files.copy(Paths.get("part1.bin"), channel)——它会自动追加到当前文件末尾 - 无需手动管理缓冲区,但要注意:多次
copy()到同一 channel 是追加行为,前提是 channel 没有被截断或重置
处理超大数量小文件时的注意事项
如果小文件成千上万个,频繁创建/销毁流可能带来系统开销,需稍作优化:
立即学习“Java免费学习笔记(深入)”;
- 避免在循环内反复 new File / Paths —— 提前构建好路径列表
- 不建议用
ByteArrayOutputStream先合并再写盘,极易 OOM - 若需校验合并完整性(如 MD5),可在写入每段后更新摘要对象,而不是合并完再算全量
- 考虑加简单日志,例如 “已写入第 57 个文件(xxx.bin, 245KB)”,便于中断恢复定位
不推荐的做法
以下方式看似方便,实则容易出错或低效:
- 用 Scanner 或 BufferedReader 读取再写 String:会触发字符编码转换,破坏二进制数据
- 用 DataOutputStream.writeUTF() 或 writeBytes():添加额外长度头或换行,不是纯字节拼接
-
把所有文件读进一个 List
再合并 :内存占用不可控,尤其小文件多但单个几 MB 时极易崩溃
关键就三点:用字节流、顺序写入、缓冲读取。不需要第三方库,标准 JDK 就足够可靠。


















