Java文件上传解压

目录结构

在这里插入图片描述

工具类

枚举

定义文件类型

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 {
    @Autowired
    private 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 {

    @Autowired
    private fileTypes fileTypes;
    
    
    @Override
    public 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>

该代码仅实现了zip的解压

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

浪波湾

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值