sequenceinputstream 用于按顺序拼接多个已打开的 inputstream,不负责文件查找、排序或打开;需先按命名规则(如序号或日期)获取并排序日志文件,再为每个文件创建 fileinputstream,封装为 enumeration 后传入,推荐用 inputstreamreader 和 bufferedreader 指定编码读取。

明确 SequenceInputStream 的作用边界
它只是把多个 已打开的 InputStream 按顺序串成一个流,不负责查找文件、排序或自动打开文件。所以关键步骤是:先获取有序的文件列表 → 为每个文件创建 FileInputStream → 收集进 Enumeration → 传给 SequenceInputStream。
按命名规则整理日志文件并排序
日志碎片通常有规律,比如:app.log.1、app.log.2、app.log.3,或按日期:app-20240501.log、app-20240502.log。必须确保顺序正确,否则日志内容会错乱。
- 用
Files.list()或File.listFiles()获取候选文件 - 用正则匹配识别日志碎片(如
app\.log\.\d+或app-\d{8}\.log) - 提取序号或时间戳,转为可比较的整数/LocalDate,再排序
构建 Enumeration 并初始化 SequenceInputStream
Java 旧版 API 要求传入 Enumeration<inputstream></inputstream>,可用 Collections.enumeration(list) 转换 ArrayList。
- 每个文件用
new FileInputStream(file)打开,建议用 try-with-resources 管理单个流(注意:SequenceInputStream 本身需单独关闭,它会依次关闭内部所有流) - 避免提前关闭任一 FileInputStream,否则后续读取会抛 IOException
- 示例片段:
List<inputstream> streams = new ArrayList();<br>
for (File f : sortedFiles) {<br>
streams.add(new FileInputStream(f));<br>
}<br>
Enumeration<inputstream> e = Collections.enumeration(streams);<br>
try (SequenceInputStream seq = new SequenceInputStream(e)) {<br>
// 用 seq.read() 或包装 BufferedReader 逐行读取<br>
}</inputstream></inputstream>
实际读取时注意缓冲与编码
日志通常是文本,直接用 SequenceInputStream 读字节容易乱码或换行丢失。推荐包装成带编码的 BufferedReader:
- 用
new InputStreamReader(seq, StandardCharsets.UTF_8)指定编码 - 再套
BufferedReader提升效率,支持readLine() - 注意:SequenceInputStream 在某个子流末尾自动切换到下一个,BufferedReader 会无缝衔接,无需手动干预
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











