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

如何解压.tar.gz格式MultipartFile并转为List<File>或List<FileItem>

解决.tar.gz格式MultipartFile解压并存入列表的问题

下面是补全并优化后的代码,可实现将解压后的文件存入List<File>或List<FileItem>:

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorInputStream;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public void importFilesTar(MultipartFile file) throws ContentRepositoryDaoException, Exception {
    List<File> files = new ArrayList<>();
    List<DiskFileItem> fileItems = 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.getNextEntry()) != null) {
            // 跳过目录,只处理实际文件
            if (entry.isDirectory()) {
                continue;
            }

            // 先把当前文件内容读到字节数组,避免重复读取流(流只能单向读取)
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            byte[] buffer = new byte[1024 * 8];
            int readLen;
            while ((readLen = tarIn.read(buffer)) != -1) {
                baos.write(buffer, 0, readLen);
            }
            byte[] fileContent = baos.toByteArray();

            // --- 方式1:存入List<File>(创建临时文件)---
            File tempFile = File.createTempFile("tar_temp_", "_" + entry.getName());
            try (OutputStream out = new FileOutputStream(tempFile)) {
                out.write(fileContent);
            }
            // 可选:添加JVM退出时自动删除临时文件的逻辑
            tempFile.deleteOnExit();
            files.add(tempFile);

            // --- 方式2:存入List<FileItem>(以DiskFileItem为例)---
            DiskFileItem fileItem = new DiskFileItem(
                    entry.getName(),
                    "application/octet-stream",
                    false,
                    entry.getName(),
                    (int) entry.getSize(),
                    null
            );
            try (OutputStream itemOut = fileItem.getOutputStream()) {
                itemOut.write(fileContent);
            }
            fileItems.add(fileItem);
        }
    }
}

核心要点说明

  • 过滤目录条目:tar包会包含目录结构,通过entry.isDirectory()判断并跳过,只处理实际文件。
  • 流读取优化:将文件内容先读到字节数组,避免重复读取TarArchiveInputStream(流是单向的,读完一次后无法回溯)。
  • 资源自动管理:使用try-with-resources语法,确保所有输入输出流在使用后自动关闭,杜绝资源泄漏。
  • 临时文件清理:通过tempFile.deleteOnExit()在JVM退出时自动删除临时文件,避免磁盘空间浪费;也可在业务逻辑完成后手动调用tempFile.delete()。
  • FileItem依赖:若使用DiskFileItem,需引入Apache Commons FileUpload依赖,Maven配置示例:
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.5</version>
</dependency>

如果只需要其中一种列表,直接删除对应方式的代码即可简化逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 22:09:36