sequenceinputstream 合并分片的核心是有序串联流:需数字提取+自然排序确保分片顺序,用 vector.elements() 构建 enumeration,仅管理 sequenceinputstream 和 fileoutputstream 的资源,避免手动关闭子流;分片量大、需校验或高吞吐时应换方案。
用 sequenceinputstream 合并多个离散文件分片,本质是把它们按序“串成一条逻辑流”,再一次性写入目标文件。它不复制数据、不创建中间文件,只控制读取顺序——关键在“有序”和“无缝”,而难点往往藏在排序和资源管理里。
确保分片文件严格按序排列
分片命名混乱(比如 part1.dat、part10.dat、part2.dat)会导致内容错位。字符串排序会让 part10 排在 part2 前面,结果第 10 块数据插进第 2 块位置,整个文件就损坏了。
- 优先用数字提取+自然排序:对每个文件名用正则
"\D+"去除非数字字符,转成整数再比较 - 排序操作必须在创建 FileInputStream 之前完成;一旦流打开,顺序就固定了
- 避免依赖
Arrays.sort(files, Comparator.comparing(File::getName)),它只适合纯数字前缀且位数一致的情况(如 part01、part02)
用 Vector + Enumeration 构建可串联的输入流集合
SequenceInputStream 的多流构造器只接受 Enumeration extends InputStream>,不能直接传 List 或 Stream。Vector.elements() 是目前最稳妥的获取方式——尽管 Vector 已过时,但这是 API 限制下的务实选择。
OpenJDK 24 Windows x64 官方参考实现(24+36),适合 Windows 环境进行 Java 开发、编译、运行和版本兼容性验证。
- 不要用
Arrays.asList(...).elements(),编译会失败(Arrays.ArrayList 没有 elements 方法) - 每个分片单独 new 一个 FileInputStream,不能复用同一个流对象
- 构造 SequenceInputStream 后,它内部会按 Enumeration 返回顺序逐个读取,读完一个自动切换下一个
安全写入并避免常见资源陷阱
SequenceInputStream 是“单向消耗型”:读完即关闭所有子流,不可重复读取。手动 close 子流会抛出 “Stream closed” 异常。
- 只用 try-with-resources 管理 SequenceInputStream 和 FileOutputStream,子流交给它自动关
- 加 BufferedOutputStream 提升写入性能,尤其对百 MB 以上文件效果明显
- 建议边读边累计字节数,最终与预期总大小比对,防止某一分片为空或读取中断却无感知
什么情况下别硬套 SequenceInputStream
它适合顺序确定、无需跳读、不追求断点续传的场景。如果遇到以下情况,换方案更稳:
- 分片数量极大(几千个),Vector 内存开销明显 → 改用 Files.copy 循环追加
- 需要校验每块 MD5 或跳过损坏分片 → 自定义遍历 + 单独异常处理更灵活
- 对吞吐要求极高(如 GB 级归档)→ FileChannel.transferFrom 在部分系统上更快,但要注意 position 控制










