You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SpringBoot中解压上传.tar.gz文件时保留原目录结构

解决方案:保留tar.gz目录结构并生成List

你的核心需求是让每个FileItem携带原始压缩包内的相对目录路径,这样后续处理时就能还原目录结构。关键在于利用TarArchiveEntry自带的路径信息,同时优化文件读取逻辑,具体修改如下:

修改后的代码

private List<FileItem> unTarFile(MultipartFile file) throws Exception{
    List<FileItem> files = new ArrayList<>();
    
    // 使用try-with-resources自动关闭流,避免资源泄漏
    try (InputStream in = file.getInputStream();
         GzipCompressorInputStream gzipIn = new GzipCompressorInputStream(in);
         TarArchiveInputStream tarIn = new TarArchiveInputStream(gzipIn)) {
        
        TarArchiveEntry entry;
        // 遍历压缩包内的所有条目
        while ((entry = tarIn.getNextTarEntry()) != null) {
            // 跳过目录条目,只处理文件
            if (entry.isDirectory()) {
                continue;
            }
            
            // entry.getName() 直接返回压缩包内文件的完整相对路径(如dir1/file1)
            String entryRelativePath = entry.getName();
            String mimeType = URLConnection.guessContentTypeFromName(entryRelativePath);
            
            // 创建FileItem时,传入完整相对路径作为文件名
            FileItem fileItem = new DiskFileItem(
                "fileData", 
                mimeType, 
                false, 
                entryRelativePath, 
                (int) entry.getSize(), 
                null
            );
            
            // 用缓冲区循环读取,避免大文件导致内存溢出
            try (OutputStream out = fileItem.getOutputStream()) {
                byte[] buf = new byte[8192]; // 8KB缓冲区,可根据需求调整
                int readBytes;
                while ((readBytes = tarIn.read(buf)) != -1) {
                    out.write(buf, 0, readBytes);
                }
            }
            
            files.add(fileItem);
        }
    }
    return files;
}

关键说明

  1. 保留目录路径:TarArchiveEntry.getName()会直接返回文件在压缩包内的完整相对路径(比如dir2/file2),将这个路径作为DiskFileItem的文件名参数,每个FileItem就会携带原始目录结构信息。
  2. 跳过目录条目:压缩包内的目录本身不需要转为FileItem,通过entry.isDirectory()判断后跳过即可,文件的路径信息已经足够还原目录结构。
  3. 优化读取逻辑:原代码一次性把整个文件读入内存,大文件场景下容易触发OOM,改用固定大小缓冲区循环读取更安全高效。
  4. 自动资源管理:使用try-with-resources语法,确保所有输入输出流自动关闭,避免资源泄漏问题。

后续还原目录结构示例

如果需要将这些FileItem写入磁盘并还原目录,只需根据FileItem.getName()的路径创建父目录即可:

// 目标根目录
String targetRootDir = "/your/target/directory";
for (FileItem item : files) {
    File targetFile = new File(targetRootDir, item.getName());
    // 创建父目录(如果不存在)
    if (!targetFile.getParentFile().exists()) {
        targetFile.getParentFile().mkdirs();
    }
    // 将FileItem写入目标文件
    item.write(targetFile);
}

内容的提问来源于stack exchange,提问作者user1971376

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 14:09:25