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的解压

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/921271.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

CSRF保护--laravel进阶篇

laravel对csrf非常重视&#xff0c;专门针对csrf作出了很多的保护。如果您是刚刚接触laravel的路由不久&#xff0c;那么您可能对于web.php路由文件的post请求很疑惑&#xff0c;因为get请求很顺利&#xff0c;而post请求则可能会遭遇失败。其中一个失败的原因是由于laravel的c…

jupyter notebook的 markdown相关技巧

目录 1 先选择为markdown类型 2 开关技巧 2.1 运行markdown 2.2 退出markdown显示效果 2.3 注意点&#xff1a;一定要 先选择为markdown类型 3 一些设置技巧 3.1 数学公式 3.2 制表 3.3 目录和列表 3.4 设置各种字体效果&#xff1a;加粗&#xff0c;斜体&#x…

【GAT】 代码详解 (1) 运行方法【pytorch】可运行版本

GRAPH ATTENTION NETWORKS 代码详解 前言0.引言1. 环境配置2. 代码的运行2.1 报错处理2.2 运行结果展示 3.总结 前言 在前文中&#xff0c;我们已经深入探讨了图卷积神经网络和图注意力网络的理论基础。还没看的同学点这里补习下。接下来&#xff0c;将开启一个新的阶段&#…

redis工程实战介绍(含面试题)

文章目录 redis单线程VS多线程面试题**redis是多线程还是单线程,为什么是单线程****聊聊redis的多线程特性和IO多路复用****io多路复用模型****redis如此快的原因** BigKey大批量插入数据测试数据key面试题海量数据里查询某一固定前缀的key如果生产上限值keys * &#xff0c;fl…

神经网络问题之二:梯度爆炸(Gradient Explosion)

梯度爆炸&#xff08;Gradient Explosion&#xff09;是神经网络训练过程中常见的一个问题&#xff0c;它指的是在反向传播过程中&#xff0c;梯度值变得非常大&#xff0c;超出了网络的处理范围&#xff0c;从而导致权重更新变得不稳定甚至不收敛的现象。 一、产生原因 梯度爆…

小杨的N字矩阵c++

题目描述 小杨想要构造一个m*m 的 N 字矩阵&#xff08; m为奇数&#xff09;&#xff0c;这个矩阵的从左上角到右下角的对角线、第1 列和第m 列都 是半角加号 &#xff0c;其余都是半角减号 - 。例如&#xff0c;一个 5*5 的 N 字矩阵如下&#xff1a; --- -- -- -- --- 请…

2024 年企业中的生成式 AI 现状

2024: The State of Generative AI in the Enterprise - Menlo Ventures 企业 AI 格局正在被实时改写。随着试点&#xff08;Pilot&#xff09;让位于生产&#xff08;Production&#xff09;&#xff0c;我们对 600 名美国企业 IT 决策者进行了调查&#xff0c;以揭示新出现的…

Ubuntu24虚拟机-gnome-boxes

推荐使用gnome-boxes&#xff0c; virtualbox构建失败&#xff0c;multipass需要开启防火墙 sudo apt install gnome-boxes创建完毕&#xff5e;

Haystack 的开源开发 LLM 应用设计框架

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

leetcode 919.完全二叉树插入器

1.题目要求: 完全二叉树 是每一层&#xff08;除最后一层外&#xff09;都是完全填充&#xff08;即&#xff0c;节点数达到最大&#xff09;的&#xff0c;并且所有的节点都尽可能地集中在左侧。设计一种算法&#xff0c;将一个新节点插入到一棵完全二叉树中&#xff0c;并在…

提升性能测试效率与准确性:深入解析JMeter中的各类定时器

在软件性能测试领域&#xff0c;Apache JMeter是一款广泛使用的开源工具&#xff0c;它允许开发者模拟大量用户对应用程序进行并发访问&#xff0c;从而评估系统的性能和稳定性。在进行性能测试时&#xff0c;合理地设置请求之间的延迟时间对于模拟真实用户行为、避免服务器过载…

Python + 深度学习从 0 到 1(00 / 99)

希望对你有帮助呀&#xff01;&#xff01;&#x1f49c;&#x1f49c; 如有更好理解的思路&#xff0c;欢迎大家留言补充 ~ 一起加油叭 &#x1f4a6; 欢迎关注、订阅专栏 【深度学习从 0 到 1】谢谢你的支持&#xff01; ⭐ 什么是深度学习&#xff1f; 人工智能、机器学习与…

亚信安全发布《2024年第三季度网络安全威胁报告》

《亚信安全2024年第三季度网络安全威胁报告》的发布旨在从一个全面的视角解析当前的网络安全威胁环境。此报告通过详尽梳理和总结2024年第三季度的网络攻击威胁&#xff0c;目的是提供一个准确和直观的终端威胁感知。帮助用户更好地识别网络安全风险&#xff0c;并采取有效的防…

ROS机器视觉入门:从基础到人脸识别与目标检测

前言 从本文开始&#xff0c;我们将开始学习ROS机器视觉处理&#xff0c;刚开始先学习一部分外围的知识&#xff0c;为后续的人脸识别、目标跟踪和YOLOV5目标检测做准备工作。我采用的笔记本是联想拯救者游戏本&#xff0c;系统采用Ubuntu20.04&#xff0c;ROS采用noetic。 颜…

利用c语言详细介绍下选择排序

选择排序&#xff08;Selection sort&#xff09;是一种简单直观的排序算法。它是每次选出最小或者最大的元素放在开头或者结尾位置&#xff08;采用升序的方式&#xff09;&#xff0c;最终完成列表排序的算法。 一、图文介绍 我们还是使用数组【10&#xff0c;5&#xff0c;3…

candence: 非金属化孔制作

非金属化孔制作 以下面这个RJ45接口为例 1、打开pad designer 只需要设置开始、结束层即可。 保存 来直观看下非金属化孔和金属化孔的区别&#xff1a;

用宏实现简单的计算器

大家好&#xff0c;那么经过我们前面几期的学习&#xff0c;我们对宏有了一定的了解&#xff0c;那么我们今天就来试试实现一个简单的加减乘除运算。 我们的思路是使用三目操作符来分别进行加减和乘除的运算&#xff0c;然后用if判断来”进入相关的判断体进而来进行计算。当然…

Postman之newman

系列文章目录 1.Postman之安装及汉化基本使用介绍 2.Postman之变量操作 3.Postman之数据提取 4.Postman之pm.test断言操作 5.Postman之newman Postman之newman 1.基础环境node安装1.1.配置环境变量1.2.安装newman和html报告组件 2.newman运行 newman可以理解为&#xff0c;没有…

用python简单集成一个分词工具

本部分记录如何利用Python进行分词工具集成&#xff0c;集成工具可以实现运行无环境要求&#xff0c;同时也更方便。 该文章主要是记录&#xff0c;知识点不是特别多&#xff0c;欢迎访问个人博客&#xff1a;https://blog.jiumoz.top/archives/fen-ci-gong-ju-ji-cheng 成品展…

CMake + mingw + opencv

由于是在windows下开发&#xff0c;因此下载的是windows版本的安装程序&#xff0c;如图&#xff1a; 下载的是 MSVC 编译的 OpenCV&#xff0c;但由于我一般使用的是JetBrains的开发工具&#xff0c;并且为了方便跨平台&#xff0c;我一般也是使用cmakemingw编译&#xff0c;这…