使用Java TarInputStream读取嵌套tar.gz压缩包内的文件名称
嵌套tar.gz内层文件读取解决方案
报错原因
你代码抛出FileNotFoundException的核心原因是内层tar.gz文件并未存储在本地磁盘,而是作为外层tar.gz的一个条目存在于外层流数据中,直接通过FileInputStream读取文件名无法定位到流内数据。
正确实现逻辑
- 遍历外层
TarInputStream找到后缀为.tar.gz的非目录条目 - 直接使用外层
TarInputStream读取该条目的二进制内容,无需落地到本地磁盘 - 将读取到的字节流包装为
GZIPInputStream后再封装为TarInputStream,即可直接遍历内层压缩包的所有条目
可运行代码示例
try (TarInputStream outerTis = getStreamRemoteTarGz(url)) { TarEntry outerEntry; // 遍历外层tar.gz所有条目 while ((outerEntry = outerTis.getNextEntry()) != null) { // 筛选内层tar.gz文件(排除名称后缀匹配的目录) if (!outerEntry.isDirectory() && outerEntry.getName().endsWith(".tar.gz")) { // 直接从外层流读取当前条目的内容,构造内层TarInputStream try (TarInputStream innerTis = new TarInputStream(new GZIPInputStream(outerTis))) { TarEntry innerEntry; // 遍历内层tar.gz所有条目 while ((innerEntry = innerTis.getNextEntry()) != null) { // 输出内层文件名称,此处可扩展读取文件内容的逻辑 System.out.println("内层文件:" + innerEntry.getName()); } } } } }
注意事项
- 外层
TarInputStream在获取到内层tar.gz条目后,后续的读取操作默认都是读取当前条目的内容,不需要额外的读取逻辑 - try-with-resources会自动管理流的关闭,无需手动关闭内层或外层流
- 增加非目录判断可以避免匹配到名称以
.tar.gz结尾的目录,减少异常场景
内容的提问来源于stack exchange,提问作者Oguz Aktas
相关产品推荐
相关产品推荐

