Java 压缩多个文件为zip包(中间不生成临时文件,直接压缩为zip二进制流),以及解压zip包二进制流为文件

news2025/2/21 22:24:48

Java 压缩多个文件为zip包及解压zip包以及压缩多文件为zip文件流解压zip二进制流(中间不生成临时文件,直接压缩为zip二进制流,并验证解压)

    • 1. 效果图
    • 2. 源码

这篇博客将提供俩种方法,

  1. 提前生成要压缩的多个文件,然后读取文件夹多层或一层去遍历压缩zip包
  2. 直接用原始文件名称及二进制流,压缩返回zip包二进制流,中间不生成冗余文件;
    很明显方法2更优一些;
  3. 解压zip文件或者zip文件流验证;

1. 效果图

压缩俩个文件到zip包,并分别解析zip包文件及zip二进制流,打印文件及文件内容详情效果图如下:

在这里插入图片描述

2. 源码

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;


public class FileUtil {

    public static void main(String[] args) throws Exception {
        long timeStamp = System.currentTimeMillis();
        String uuid = UUID.randomUUID().toString();
        // 生成本地文件,然后压缩,压缩完成清除本地文件及冗余文件夹
        zipTest1(uuid, timeStamp);

        // 不生成中间文件,直接使用文件名称+文件流进行压缩 更优
        zipTest2(uuid, timeStamp);
    }

    private static void zipTest2(String uuid, long timeStamp) throws IOException {
        String zipFileName = String.format("%s_%s.zip", uuid, timeStamp);
        String imgFileName = String.format("%s_%s_%s.json", "img", uuid, timeStamp);
        String referInfoFile = String.format("%s_%s_%s.json", "ref", uuid, timeStamp);

        String[] fileNames = new String[]{imgFileName, referInfoFile};
        List<byte[]> bytesList = new ArrayList<>();
        byte[] file0 = imgFileName.toString().getBytes();
        byte[] file1 = referInfoFile.toString().getBytes();
        bytesList.add(file0);
        bytesList.add(file1);

        // zip压缩流
        byte[] rodZip = packageZipToBytes(fileNames, bytesList);

        readAndParseZip(zipFileName, rodZip);
    }

    private static void zipTest1(String uuid, long timeStamp) throws Exception {
        String path = System.getProperty("user.dir") + File.separator + uuid + "_" + timeStamp + File.separator;
        String resPath = System.getProperty("user.dir") + File.separator + "out" + File.separator + uuid + "_" + timeStamp;

        deleteDirectory(path);
        delOrCreateDir(path);
        delOrCreateDir(resPath);
        String imgFileName = String.format("%s%s_%s_%s.json", path, "img", uuid, timeStamp);
        String referInfoFile = String.format("%s%s_%s_%s.json", path, "ref", uuid, timeStamp);
        try (FileWriter fileWriter = new FileWriter(referInfoFile)) {
            fileWriter.write(referInfoFile.toString());
        }
        try (FileWriter fileWriter = new FileWriter(imgFileName)) {
            fileWriter.write(imgFileName.toString());
        }

        System.out.println("zip start ---------------" + System.currentTimeMillis());
        FileUtil test3 = new FileUtil();
        String packagePath = path;  //选中的文件夹
        test3.packageZip(packagePath, resPath + ".zip");
        System.out.println("zip finish ---------------" + System.currentTimeMillis());

        // 删除冗余文件,文件夹
        deleteDirectory(path);
        deleteDirectory(resPath);
        deleteDirectory(resPath);
    }

    /**
     * 压缩多个文件为zip包文件流
     *
     * @param fileNames 文件名称
     * @param byteLists 文件流
     * @return
     */
    public static byte[] packageZipToBytes(String[] fileNames, List<byte[]> byteLists) throws IOException {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ZipOutputStream zipOutputStream = null;
        try {
            zipOutputStream = new ZipOutputStream(bos);
            for (int i = 0; i < fileNames.length; i++) {
                String fileName = fileNames[i];
                fileName = fileName.substring(fileName.lastIndexOf(File.separator) + 1);
                byte[] content = byteLists.get(i);
                // 依次对每个文件都压缩
                try {
                    zipOutputStream.putNextEntry(new ZipEntry(fileName));
                    zipOutputStream.write(content);
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            zipOutputStream.close();
            bos.close();
        } catch (FileNotFoundException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        byte[] zipOutBytes = bos.toByteArray();
/*        OutputStream fos = new FileOutputStream("D:\\study\\ark-common-model\\out\\aaaaaaaa_1689583754986.zip");
        fos.write(zipOutBytes, 0, zipOutBytes.length);
        fos.close();*/

        return zipOutBytes;
    }

    private static void readAndParseZip(String zipFilePath, byte[] rodZip) {
        ByteArrayInputStream fis = null;
        FileInputStream fileInputStream = null;
        ZipInputStream zis = null;
        try {
            if (rodZip != null) {
                fis = new ByteArrayInputStream(rodZip);
                zis = new ZipInputStream(fis);
            } else {
                fileInputStream = new FileInputStream(zipFilePath);
                zis = new ZipInputStream(fileInputStream);
            }

            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                // 如果该项是一个文件
                if (!zipEntry.isDirectory()) {
                    String fileName = zipEntry.getName();
                    ByteArrayOutputStream bos = new ByteArrayOutputStream();

                    byte[] buffer = new byte[1024];
                    int len;
                    while ((len = zis.read(buffer)) > 0) {
                        bos.write(buffer, 0, len);
                    }
                    // 将解压出的文件流输出到控制台
                    String content = bos.toString();
                    System.out.println("fileName: " + fileName + ",content: " + content);
                }
                zis.closeEntry();
                zipEntry = zis.getNextEntry();
            }

            zis.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void delOrCreateDir(String imgPath) {
        File file = new File(imgPath);

        if (!file.getParentFile().exists()) {
            //上级目录不存在,创建上级目录
            file.getParentFile().mkdirs();
        } else {
//            FileUtils.deleteFolder(imgPath);
        }
        file.mkdirs();
    }

    /**
     * 根据路径删除指定的目录或文件,无论存在与否
     *
     * @param sPath 要删除的目录或文件
     * @return 删除成功返回 true,否则返回 false。
     */
    public static boolean deleteFolder(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 判断目录或文件是否存在
        if (!file.exists()) {  // 不存在返回 false
            return flag;
        } else {
            // 判断是否为文件
            if (file.isFile()) {  // 为文件时调用删除文件方法
                return deleteFile(sPath);
            } else {  // 为目录时调用删除目录方法
                return deleteDirectory(sPath);
            }
        }
    }

    /**
     * 删除单个文件
     *
     * @param sPath 被删除文件的文件名
     * @return 单个文件删除成功返回true,否则返回false
     */
    public static boolean deleteFile(String sPath) {
        boolean flag = false;
        File file = new File(sPath);
        // 路径为文件且不为空则进行删除
        if (file.isFile() && file.exists()) {
            file.delete();
            flag = true;
        }
        return flag;
    }

    /**
     * 删除目录(文件夹)以及目录下的文件
     *
     * @param sPath 被删除目录的文件路径
     * @return 目录删除成功返回true,否则返回false
     */
    public static boolean deleteDirectory(String sPath) {
        boolean flag = false;
        //如果sPath不以文件分隔符结尾,自动添加文件分隔符
        if (!sPath.endsWith(File.separator)) {
            sPath = sPath + File.separator;
        }
        File dirFile = new File(sPath);
        //如果dir对应的文件不存在,或者不是一个目录,则退出
        if (!dirFile.exists() || !dirFile.isDirectory()) {
            return false;
        }
        flag = true;
        //删除文件夹下的所有文件(包括子目录)
        File[] files = dirFile.listFiles();
        for (int i = 0; i < files.length; i++) {
            //删除子文件
            if (files[i].isFile()) {
                flag = deleteFile(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            } //删除子目录
            else {
                flag = deleteDirectory(files[i].getAbsolutePath());
                if (!flag) {
                    break;
                }
            }
        }
        if (!flag) {
            return false;
        }
        //删除当前目录
        if (dirFile.delete()) {
//            dirFile.getParentFile().delete();
            return true;
        } else {
//            dirFile.getParentFile().delete();
            return false;
        }
    }


    public void packageZip(String filesPath, String resPath) throws Exception {
        // 要被压缩的文件夹
        File file = new File(filesPath);   //需要压缩的文件夹
        File zipFile = new File(resPath);
        ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
        isDirectory(file, zipOut, "", true);   //判断是否为文件夹
        zipOut.close();
    }

    public void isDirectory(File file, ZipOutputStream zipOutputStream, String filePath, boolean flag) throws
            IOException {
        //判断是否为问加减
        if (file.isDirectory()) {
            File[] files = file.listFiles();  //获取该文件夹下所有文件(包含文件夹)
            filePath = flag == true ? file.getName() : filePath + File.separator + file.getName();   //首次为选中的文件夹,即根目录,之后递归实现拼接目录
            for (int i = 0; i < files.length; ++i) {
                //判断子文件是否为文件夹
                if (files[i].isDirectory()) {
                    System.out.println("-----" + files[i].getName());
                    //进入递归,flag置false 即当前文件夹下仍包含文件夹
                    isDirectory(files[i], zipOutputStream, filePath, false);
                } else {
                    System.out.println("fileName: " + files[i].getName());
                    //不为文件夹则进行压缩
                    InputStream input = new FileInputStream(files[i]);
                    zipOutputStream.putNextEntry(new ZipEntry(files[i].getName()));
                    int temp = 0;
                    while ((temp = input.read()) != -1) {
                        zipOutputStream.write(temp);
                    }
                    input.close();
                }
            }
        } else {
            //将子文件夹下的文件进行压缩
            InputStream input = new FileInputStream(file);
            zipOutputStream.putNextEntry(new ZipEntry(file.getPath()));
            int temp = 0;
            while ((temp = input.read()) != -1) {
                zipOutputStream.write(temp);
            }
            input.close();
        }
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vscode debug的方式

在.vscode文件夹下建立launch.json 例子1&#xff1a;调试python 来自 https://github.com/chunleili/tiPBD/tree/amg {"version": "0.2.0","configurations": [{"name": "hpbd 5 5","type": "python&quo…

港联证券|通胀和通缩的区别?通胀对股市有什么影响?

在市场经济上&#xff0c;通货紧缩和通货膨胀是两种比较常见的两种经济现象&#xff0c;那么&#xff0c;通胀和通缩的差异&#xff1f;通胀对股市有什么影响&#xff1f; 港联证证券为大家预备了相关内容&#xff0c;以供参考。 通胀和通缩存在以下差异&#xff1a; 1、定义…

初识操作系统

操作系统 文章目录 操作系统一、上次的问题二、什么是操作系统(Operator System&#xff09;设计操作系统的目的 三、操作系统上下层分别是什么四、先描述&#xff0c;后组织 一、上次的问题 为什么程序运行之前必须先加载到内存&#xff1f; 因为可执行程序&#xff08;文件…

数字化时代,如何做好用户体验与应用性能管理​

引言 随着数字化时代的到来&#xff0c;各个行业的应用系统从传统私有化部署逐渐转向公有云、行业云、微服务&#xff0c;这种变迁给运维部门和应用部门均带来了较大的挑战。基于当前企业 IT 运维均为多部门负责&#xff0c;且使用多种运维工具&#xff0c;因此&#xff0c;当…

【27】SCI易中期刊推荐——计算机科学机器人学(中科院2区)

💖💖>>>加勒比海带,QQ2479200884<<<💖💖 🍀🍀>>>【YOLO魔法搭配&论文投稿咨询】<<<🍀🍀 ✨✨>>>学习交流 | 温澜潮生 | 合作共赢 | 共同进步<<<✨✨ 📚📚>>>人工智能 | 计算机视觉…

arcgis建筑密度容积率覆盖率

大多数研究会把覆盖率当作建筑密度。 用覆盖率更恰当一些。 建筑覆盖率&#xff1a; 建筑物占据面积/街区面积 [Sum_area]/ ([area]*1000000) 排序检查数据&#xff0c;最大值0.75&#xff0c;最小值0. 建筑覆盖率&#xff0c;建筑密度的范围都应该在0-1之内&#xff0c;不是…

linux之Ubuntu系列(三)远程管理指令☞SSH 高级应用 RSA非对称加密 以及免密登录,配置别名

对称加密 、非对称加密 1、对称加密中加密和解密使用的秘钥是同一个&#xff1b;非对称加密中采用两个密钥&#xff0c;一般使用公钥进行加密&#xff0c;私钥进行解密。 2、对称加密解密的速度比较快&#xff0c;非对称加密和解密花费的时间长、速度相对较慢。 3、对称加密的…

【文末送书】AIGC时代的数据分析与可视化

欢迎关注博主 Mindtechnist 或加入【智能科技社区】一起学习和分享Linux、C、C、Python、Matlab&#xff0c;机器人运动控制、多机器人协作&#xff0c;智能优化算法&#xff0c;滤波估计、多传感器信息融合&#xff0c;机器学习&#xff0c;人工智能等相关领域的知识和技术。搜…

C语言实现:offsetof(OFFSETOF)宏的实现

C语言实现&#xff1a;offsetof宏的实现 offsetof:求结构体成员的偏移量 offsetof:求结构体成员的偏移量 直接上代码&#xff1a; #define OFFSETOF(type,member) ((size_t)(&(((type*)0)->member))) 图解&#xff1a; 图中测试原码&#xff1a; #include<stdi…

Centos Stream9安装vim代码提示coc的详细过程

Centos Stream9安装vim代码提示coc的安装步骤&#xff1a; 1、安装字体 https://github.com/ryanoasis/nerd-fonts/releaseshttps://github.com/ryanoasis/nerd-fonts/releases wget https://github.com/ryanoasis/nerd-fonts/releases/download/v3.0.2/Hack.tar.xz 下载后&a…

短视频seo抖音矩阵源码开发搭建技术解析

一、 短视频seo抖音矩阵源码开发需要考虑以下几个方面&#xff1a; 技术选型&#xff1a;选择合适的开发语言、框架和数据库&#xff0c;常用的开发语言有Java、PHP等&#xff0c;常用的框架有Spring、Django等&#xff0c;常用的数据库有MySQL、MongoDB等。 服务器的选择&…

若依框架系列教程(RuoYi-Vue前后端分离版本)

视频教程见评论 相关文档&#xff1a; https://www.cnblogs.com/52mqq/p/16068330.html 若依 Ruo-Yi&#xff08;分离版&#xff09;学习笔记 若依框架RuoYi项目运行启动教程【傻瓜式教程】_若依前端怎么启动_紫陌~的博客-CSDN博客 一定要看上面那个傻瓜式教程&#xff0c;…

MediaType的常用类型-GPT问答

MediaType的常用类型-GPT问答 MediaType是一个枚举类&#xff0c;包含了常见的媒体类型。下面是一些常用的MediaType类型&#xff1a; APPLICATION_JSON&#xff1a;JSON格式的数据APPLICATION_XML&#xff1a;XML格式的数据APPLICATION_FORM_URLENCODED&#xff1a;表单格式的…

Docker 常用命令速览

Shawn的学习笔记Descriptionhttps://study.chenkequan.cn/#/Spring%E7%B3%BB%E5%88%97/Docker/Docker完整笔记查看我个人网站。 机缘巧合&#xff0c;我想把实验室的网重新配一遍&#xff0c;配置成自动登录校园网&#xff0c;之前配过了&#xff0c;我得到当时打了一个Docker…

盘点国内热门AI大模型

Chat-GPT问世以来&#xff0c;使得大模型一时间内火爆非凡。国内外各大科技公司也纷纷加入到大模型的研发行列中来&#xff0c;“百模之战”愈演愈烈&#xff0c;国内百度、阿里、华为等科技大厂陆续推出旗下大模型产品&#xff0c;新锐科技公司也不甘落后&#xff0c;目前不少…

【基于 GitLab 的 CI/CD 实践】01、GitLab CI/CD 基础概念

目录 一、为什么要做 CI/CD &#xff1f; 1.1 背景-传统的应用开发发布模式 问题 1.2 持续集成与持续交付 持续集成&#xff08;CI&#xff09; 持续交付&#xff08;CD&#xff09; 持续部署&#xff08;CD&#xff09; 1.3 CI/CD 的价值体现 1.4 推荐常用的 CI/CD 工…

人工智能系统将家用机器人的解决问题技能提高了80%

麻省理工学院的研究人员开发了PIGINet&#xff0c;这是一个新系统&#xff0c;旨在有效地提高家用机器人解决问题的能力&#xff0c;将规划时间缩短50-80%。 在正常情况下&#xff0c;家用机器人遵循预定义的执行任务的配方&#xff0c;这并不总是适合多样化或不断变化的环境。…

指针面试题详解

目录 前言&#xff08;数组名的总结&#xff09;&#xff1a; 一、int 型数组和 sizeof 的组合 sizeof计算原理 二、char类型和strlen&#xff08;&#xff09;组合 三、char*类型和sizeof&#xff08;&#xff09;组合&#xff08;有 \0 版本&#xff09; 四、char*类型和…

【干货】Mysql解决中文乱码

登录数据库后&#xff0c;选择数据库然后执行 MariaDB [test]> status; -------------- mysql Ver 15.1 Distrib 5.5.68-MariaDB, for Linux (x86_64) using readline 5.1Connection id: 6 Current database: test Current user: rootlocalhost SSL: …

开源人力资源管理系统OrangeHRM

什么是 OrangeHRM &#xff1f; OrangeHRM 是一个全面的人力资源管理(HRM) 系统&#xff0c;它包含任何企业所需的所有基本功能。该软件旨在支持任何规模的团队&#xff0c;包括初创企业、中小企业以及大型跨国组织。 你也可以去官方的演示站点进行体验 网址&#xff1a;https…