如何解压.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
相关产品推荐
相关产品推荐

