sequenceinputstream 是将多个 inputstream 按序串联的只读流,不缓存、不转换、不支持写入;需手动关闭各子流,适用于日志合并、分片加载等场景。

SequenceInputStream 本质是把多个 InputStream 按顺序“拼接”成一个逻辑上的单一输入流,它本身不支持写操作,也不做数据缓存或格式转换,只负责按序读取——这点常被误认为“合并文件”或“支持写入”,实际它只是读取端的串联器。
核心作用:按序读取多个输入流
它适用于需要将若干个输入源(如多个文件、字节数组、网络响应等)当作一个连续流来处理的场景,比如日志归档合并、分片资源加载、模板片段拼接等。关键点在于:所有输入流必须是只读的;读取完前一个,才自动切换到下一个;任一输入流为 null 会抛出异常。
- 构造方式有两种:
new SequenceInputStream(Enumeration<inputstream>)</inputstream>或new SequenceInputStream(InputStream, InputStream) - 推荐用
Vector<inputstream></inputstream>+Collections.enumeration()构建枚举,避免手动实现Enumeration - 每个子流会被自动关闭吗?不会。需在外部显式关闭各原始流,或使用 try-with-resources 分别管理
典型合并读取实战示例
假设有两个文本文件 a.txt 和 b.txt,想一次性读出全部内容:
InputStream a = new FileInputStream("a.txt");
InputStream b = new FileInputStream("b.txt");
Enumeration<inputstream> en = Collections.enumeration(Arrays.asList(a, b));
try (SequenceInputStream seq = new SequenceInputStream(en);
BufferedReader reader = new BufferedReader(new InputStreamReader(seq))) {
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
} finally {
// 注意:a 和 b 仍需单独关闭,除非已包含在 try-with-resources 中
a.close(); b.close();
}</inputstream>
更稳妥写法是把每个流都纳入 try-with-resources:
Java项目代码review工具。分析Git变更+完整调用链路上下文,推断业务需求,进行多维度评分和分类汇总,生成完整PRD文档。包含细粒度Java代码审查清单(Null安全、异常处理、Streams、并发、equals/hashCode、资源管理、API设计、性能、MyBatis/ORM、事务边界、SQL/DD...
- 用
Stream.of(a, b).map(InputStream::readAllBytes)预加载再合并,适合小文件 - 对大文件,保持流式读取,但确保每个原始流在
SequenceInputStream使用完毕后关闭 - 若某子流中途异常(如 IOException),后续流不会被读取,需自行捕获并决定是否跳过
常见误区与避坑提醒
容易混淆的是:它不是文件合并工具,也不处理编码、换行、边界标记等问题。例如两个 UTF-8 文件拼接后直接用 InputStreamReader 解码,若第二个文件以 BOM 开头,可能导致乱码;又如第一个流末尾无换行符,第二个流开头也无换行符,拼接后文本会连在一起。
- 不要期望它自动识别或跳过子流间的空行、分隔符
- 不能用于输出——
SequenceInputStream没有write方法,也不继承自OutputStream - 并发读取不安全:多个线程同时调用
read()可能导致错乱,应由单线程消费 - 子流长度未知时,
available()返回值不可靠,仅反映当前子流剩余字节数
替代方案参考(按场景选型)
如果目标是真正“合并文件”或需要更多控制,可考虑:
- 用
Files.copy()循环追加写入目标文件(适合持久化合并) - 用
ByteArrayInputStream+ByteArrayOutputStream内存拼接(限小数据量) - Java 9+ 可用
InputStream.concat()(静态工厂方法,语义更清晰,底层仍是 SequenceInputStream) - 复杂场景建议用 Apache Commons IO 的
SequenceInputStream增强版或自定义CompositeInputStream
不复杂但容易忽略细节。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










