目录结构
工具类
枚举
定义文件类型
public enum FileType {// 未知UNKNOWN,// 压缩文件ZIP, RAR, _7Z, TAR, GZ, TAR_GZ, BZ2, TAR_BZ2,// 位图文件BMP, PNG, JPG, JPEG,// 矢量图文件SVG,// 影音文件AVI, MP4, MP3, AAR, OGG, WAV, WAVE}
为了避免文件被修改后缀,所以这里创建了一个获取文件的真实类型工具类
import com.zipfile.zipenum.FileType;
import org.springframework.stereotype.Component;import java.io.File;
import java.io.IOException;
import java.io.InputStream;@Component
public class fileTypes {public static FileType getFileType(InputStream inputStream){
// FileInputStream inputStream =null;try{
// inputStream = new FileInputStream(file);byte[] head = new byte[4];if (-1 == inputStream.read(head)) {return FileType.UNKNOWN;}int headHex = 0;for (byte b : head) {headHex <<= 8;headHex |= b;}switch (headHex) {case 0x504B0304:return FileType.ZIP;case 0x776f7264:return FileType.TAR;case -0x51:return FileType._7Z;case 0x425a6839:return FileType.BZ2;case -0x74f7f8:return FileType.GZ;case 0x52617221:return FileType.RAR;default:return FileType.UNKNOWN;}}catch (Exception e){e.printStackTrace();}finally {try {if(inputStream!=null){inputStream.close();}} catch (IOException e) {e.printStackTrace();}}return FileType.UNKNOWN;}
解压压缩包的工具类
import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveInputStream;
import org.apache.commons.compress.archivers.sevenz.SevenZArchiveEntry;
import org.apache.commons.compress.archivers.sevenz.SevenZFile;
import com.github.junrar.Archive;
import com.github.junrar.exception.RarException;
import com.github.junrar.rarfile.FileHeader;
import org.springframework.stereotype.Component;import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;//@Component
public class decompression {/*** 解压缩tar文件* @param file 压缩包文件* @param targetPath 目标文件夹* @param delete 解压后是否删除原压缩包文件*/public static void decompressTar(File file, String targetPath, boolean delete) {try (FileInputStream fis = new FileInputStream(file);TarArchiveInputStream tarInputStream = new TarArchiveInputStream(fis)) {// 创建输出目录Path outputDir = Paths.get(targetPath);if (!Files.exists(outputDir)) {Files.createDirectories(outputDir);}TarArchiveEntry entry;while ((entry = tarInputStream.getNextTarEntry()) != null) {Path entryPath = outputDir.resolve(entry.getName());if (entry.isDirectory()) {Files.createDirectories(entryPath); // 创建子目录} else {Files.createDirectories(entryPath.getParent()); // 确保父目录存在try (OutputStream fos = Files.newOutputStream(entryPath)) {byte[] buffer = new byte[2048];int count;while ((count = tarInputStream.read(buffer)) != -1) {fos.write(buffer, 0, count);}}}}// 如果需要删除原始文件if (delete) {Files.delete(file.toPath());}} catch (IOException e) {e.printStackTrace();}}/*** 解压缩7z文件* @param file 压缩包文件* @param targetPath 目标文件夹* @param delete 解压后是否删除原压缩包文件*//*** 解压 7z 文件** @param file 压缩包文件* @param targetPath 目标文件夹* @param delete 解压后是否删除原压缩包文件*/public static void decompress7Z(File file, String targetPath, boolean delete) {try (SevenZFile sevenZFile = new SevenZFile(file)) { // 自动关闭资源// 创建输出目录Path outputDir = Paths.get(targetPath);if (!Files.exists(outputDir)) {Files.createDirectories(outputDir);}SevenZArchiveEntry entry;while ((entry = sevenZFile.getNextEntry()) != null) {Path entryPath = outputDir.resolve(entry.getName());if (entry.isDirectory()) {Files.createDirectories(entryPath); // 创建子目录} else {Files.createDirectories(entryPath.getParent()); // 确保父目录存在try (OutputStream outputStream = new FileOutputStream(entryPath.toFile())) {byte[] buffer = new byte[2048];int len;while ((len = sevenZFile.read(buffer)) != -1) {outputStream.write(buffer, 0, len);}}}}// 删除原始文件(可选)if (delete) {Files.delete(file.toPath());}} catch (IOException e) {e.printStackTrace();}}/*** 解压 RAR 文件** @param file 压缩包文件* @param targetPath 目标文件夹* @param delete 解压后是否删除原压缩包文件*/public static void decompressRAR(File file, String targetPath, boolean delete) {try (Archive archive = new Archive(file)) { // 自动关闭资源// 创建输出目录Path outputDir = Paths.get(targetPath);if (!Files.exists(outputDir)) {Files.createDirectories(outputDir);}FileHeader fileHeader;while ((fileHeader = archive.nextFileHeader()) != null) {String fileName = fileHeader.getFileNameString().trim();Path filePath = outputDir.resolve(fileName);if (fileHeader.isDirectory()) {Files.createDirectories(filePath); // 创建子目录} else {Files.createDirectories(filePath.getParent()); // 确保父目录存在try (OutputStream outputStream = new FileOutputStream(filePath.toFile())) {archive.extractFile(fileHeader, outputStream);}}}// 如果需要删除原始文件if (delete) {Files.delete(file.toPath());}} catch (RarException | IOException e) {e.printStackTrace();}}/*** 解压 ZIP 文件** @param file ZIP 文件* @param targetPath 目标文件夹* @param delete 解压后是否删除原压缩包文件*/public static void decompressZIP(File file, String targetPath, boolean delete) {try (InputStream fis = Files.newInputStream(file.toPath());ZipInputStream zipInputStream = new ZipInputStream(fis)) {// 创建输出目录Path outputDir = Paths.get(targetPath);if (!Files.exists(outputDir)) {Files.createDirectories(outputDir);}ZipEntry entry;while ((entry = zipInputStream.getNextEntry()) != null) {Path entryPath = outputDir.resolve(entry.getName());if (entry.isDirectory()) {Files.createDirectories(entryPath); // 创建子目录} else {Files.createDirectories(entryPath.getParent()); // 确保父目录存在try (FileOutputStream fos = new FileOutputStream(entryPath.toFile())) {byte[] buffer = new byte[2048];int len;while ((len = zipInputStream.read(buffer)) != -1) {fos.write(buffer, 0, len);}}}zipInputStream.closeEntry();}// 如果需要删除原始文件if (delete) {Files.delete(file.toPath());}} catch (IOException e) {e.printStackTrace();}}
}
控制层
这里使用接口的方式,接受前端传过来的文件
import com.zipfile.service.ZipService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;@RestController
@RequestMapping("zipUpload/")
public class ZipController {@Autowiredprivate ZipService zipService;@PostMapping("upload")public void zipUpload(@RequestParam("file") MultipartFile file) throws IOException {zipService.upload(file);}}
实现类
import com.zipfile.decompression.decompression;
import com.zipfile.util.fileTypes;
import com.zipfile.zipenum.FileType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;import static com.zipfile.zipenum.FileType.ZIP;@Service
public class ZipServiceImpl implements ZipService {@Autowiredprivate fileTypes fileTypes;@Overridepublic void upload(MultipartFile file) throws IOException {FileType fileType = fileTypes.getFileType(file.getInputStream());System.out.println(fileType);if (fileType == ZIP){// 创建临时文件File tempFile = convertToFile(file);decompression.decompressZIP(tempFile,"E:\\",true);}}private File convertToFile(MultipartFile file) throws IOException {// 获取文件的原始文件名String originalFilename = file.getOriginalFilename();if (originalFilename == null) {throw new IOException("文件名为空!");}// 创建临时文件String prefix = originalFilename.substring(0, originalFilename.lastIndexOf('.'));String suffix = originalFilename.substring(originalFilename.lastIndexOf('.'));File tempFile = File.createTempFile(prefix, suffix);// 将 MultipartFile 的数据写入临时文件file.transferTo(tempFile);return tempFile;}}
依赖包
这是用到的依赖包
<!-- tar 解压--><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version></dependency><!--rar解压--><dependency><groupId>com.github.junrar</groupId><artifactId>junrar</artifactId><version>7.5.4</version> <!-- 请根据最新版本选择 --></dependency>