解压TarGz文件时FileOutputStream报No such file or directory错误求助
问题分析
你遇到的No such file or directory错误,核心原因是tar包中的条目顺序不一定是先目录后文件。当处理parentdir/childdir/file这个文件条目时,parentdir/childdir这个父目录可能还没被创建(如果tar包中该目录条目在文件条目之后),直接创建文件就会失败。
你之前只在遇到目录条目时创建目录,但如果文件条目先出现,父目录不存在,FileOutputStream就会抛出找不到路径的异常。
解决方案
修改代码,处理文件条目时先确保父目录存在,同时用File类的构造方法来拼接路径,避免手动拼接路径带来的分隔符问题:
private static void extractTarGz(String filePath, String outputPath) throws IOException { try (TarArchiveInputStream tais = new TarArchiveInputStream( new GzipCompressorInputStream(new BufferedInputStream(new FileInputStream(filePath))))) { TarArchiveEntry entry; while ((entry = (TarArchiveEntry) tais.getNextEntry()) != null) { // 拼接完整输出路径 File outputFile = new File(outputPath, entry.getName()); if (entry.isDirectory()) { // 创建目录(包括父目录) outputFile.mkdirs(); } else { // 先创建父目录 File parentDir = outputFile.getParentFile(); if (!parentDir.exists()) { parentDir.mkdirs(); } int count; byte data[] = new byte[8192]; // 用固定大小缓冲区,避免大文件OOM try (FileOutputStream fos = new FileOutputStream(outputFile); BufferedOutputStream dest = new BufferedOutputStream(fos)) { while ((count = tais.read(data, 0, data.length)) != -1) { dest.write(data, 0, count); } } } } } catch (Exception e) { log.error(e); } }
关键修正点
- 路径拼接:用
new File(outputPath, entry.getName())替代手动字符串拼接,自动适配不同系统的路径分隔符(Windows的\和Linux的/)。 - 父目录预创建:处理文件时先获取
outputFile.getParentFile(),并调用mkdirs()创建所有不存在的父目录,确保文件路径有效。 - 缓冲区优化:把缓冲区大小改为固定的8192字节(或其他合理值),避免直接用
entry.getSize()创建缓冲区,防止大文件导致内存溢出。 - 资源自动关闭:用try-with-resources语法自动关闭流,避免资源泄漏。
内容的提问来源于stack exchange,提问作者user1971376
相关产品推荐
相关产品推荐

