SequenceInputStream 是 Java 中用于按顺序拼接多个 InputStream 的轻量级装饰器,通过枚举管理流队列,自动接力读取,支持两种构造方式,需用 try-with-resources 确保资源释放。

SequenceInputStream 是 Java 标准库中专为“按顺序拼接多个输入流”设计的工具类。它不真正复制数据,也不缓冲全部内容,而是以链式方式逐个读取——前一个流读完自动切换到下一个,对外呈现为一条连续、无间断的逻辑长流。这种设计轻量高效,特别适合合并多个小文件、分片资源或动态生成的输入源。
核心原理:流的顺序接力
SequenceInputStream 本质是一个装饰器(Decorator),内部维护一个枚举(Enumeration)来管理待读取的输入流队列。每次调用 read() 时,它从当前流读取;若当前流返回 -1(已结束),就自动取下一个流继续读。整个过程对上层代码完全透明,就像在读一个超大文件。
- 只支持输入流(InputStream),不能用于输出流或随机访问
- 所有被合并的流必须是阻塞式、顺序读取的典型实现(如 FileInputStream、ByteArrayInputStream)
- 不处理编码、换行或格式边界,纯粹字节级拼接
两种常用构造方式
根据输入流数量是否固定,可选择不同构造方法:
-
两个流直接拼接:适用于明确只有 A 和 B 两个源
new SequenceInputStream(inputStreamA, inputStreamB) -
多个流批量拼接:推荐用于 3 个及以上流,或流列表动态生成
先用Vector或ArrayList存储所有 InputStream,再通过Collections.enumeration(list)转为 Enumeration,传入构造函数:new SequenceInputStream(Collections.enumeration(inputStreamList))
关键操作与资源管理
使用 SequenceInputStream 时,有三个动作必须同步处理,否则容易引发资源泄漏或读取异常:
- 读取要统一走 SequenceInputStream:不要绕过它直接读原始流,否则位置错乱
-
关闭只需关 SequenceInputStream:它的
close()方法会自动调用内部每个流的close()(前提是这些流本身支持关闭) -
异常后仍需确保关闭:建议用 try-with-resources 包裹 SequenceInputStream,例如:
try (SequenceInputStream sis = new SequenceInputStream(...)) { ... }
典型实战场景示例
比如把日志分片 app-20260501.log、app-20260502.log、app-20260503.log 合并分析:
- 用循环创建对应 FileInputStream 列表
- 构造 SequenceInputStream 并用缓冲区读取(避免单字节 read 性能差)
- 边读边解析行、统计错误数或提取时间戳,无需先合并成大文件
- 整个过程内存占用恒定,只取决于缓冲区大小(如 8KB),与文件总大小无关


















