Java实现压缩解压文件

2023-11-13

关键词:ZipOutputStream    ZipInoutStream

 


最近在工作中有需求需要在浏览器中一次性下载多个文件,于是想到了使用压缩的功能。百度了一下,发现很多博客的内容都大致相同,不太方便使用。于是自己写了这么一个工具类,使用JDK中自带的ZipOutputStreamZipInoutStream实现对文件的压缩和解压。


█ 源码

/**
 * 使用方法:
 * byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes, "hello.xls").create();
 *
 * 需要添加多个文件就调用多次addFile,最后调用create生成字节数组即可
 *
 */
public class ZipUtil {

    private ZipUtil() {
        throw new RuntimeException("Illegal operation");
    }
    
    // 压缩文件
    public static ZipObject createZipObject() {
        return new ZipObject();
    }
    
    // 解压文件,参数是压缩文件字节数组
    public static UnZipObject createUnZipObject(byte[] bytes) {
        if (bytes==null || bytes.length==0) {
            throw new IllegalArgumentException("bytes is null");
        }

        return new UnZipObject(bytes);
    }
   
    public static class ZipObject {
        // 工具流
        private ZipOutputStream zos;
        // 使用带有缓冲功能的文件流存储文件
        private ByteArrayOutputStream bos;

        private ZipObject() {
            bos = new ByteArrayOutputStream();
            // 文件数据流实际存储在了bos
            zos = new ZipOutputStream(bos);
        }

        /**
         * 添加一个文件到压缩包中
         * @param fileBytes  文件的字节数组
         * @param fileName 文件名,带文件类型的,比如:hello.xlsx
         * @return
         */
        public ZipObject addFile(byte[] fileBytes, String fileName) {
            try {
                // 可以理解一个ZipEntry就表示压缩包里面的一个文件
                ZipEntry zipEntry = new ZipEntry(fileName);
                zos.putNextEntry(zipEntry);
                zos.write(fileBytes, 0, fileBytes.length);
            } catch (IOException e) {
                if (bos!=null) {
                    try {
                        bos.close();
                    } catch (IOException ee){}
                }
                if (zos!=null) {
                    try {
                        zos.close();
                    } catch (IOException ee){}
                }
            }
            return this;
        }

        /**
         * 生成压缩包的字节数组
         * @return
         */
        public byte[] create() {
            byte[] bytes = null;
            try {
                // 将数据写到ByteArrayOutputStream中
                zos.finish();
                bytes = bos.toByteArray();
                bos.flush();
                zos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (bos!=null) {
                    try {
                        bos.close();
                    } catch (IOException e){}
                }
                if (zos!=null) {
                    try {
                        zos.close();
                    } catch (IOException e){}
                }
            }

            return bytes;
        }

    }
    
    
    public static class UnZipObject {
    // 工具流
    private ZipInputStream zis;
    // 使用带有缓冲功能的文件流存储文件
    private ByteArrayInputStream bis;

    private int size;

    private UnZipObject(byte[] bytes) {
        size = bytes.length;
        bis = new ByteArrayInputStream(bytes);
        // 文件数据流实际存储在了bos
        zis = new ZipInputStream(bis);
    }

    /**
     * 获取压缩包里面的文件,一个ZipEntry表示一个文件
     * @return
     */
    public List<ZipEntry> getEntrys() {
        List<ZipEntry> list = new ArrayList<>();
        try {
            ZipEntry nextEntry = zis.getNextEntry();
            // 一个个循环读取压缩文件中的内容,放进bytes数组中
            while (nextEntry!=null) {
                byte[] bytes = new byte[size];
                zis.read(bytes);
                nextEntry.setExtra(bytes);
                list.add(nextEntry);
                nextEntry = zis.getNextEntry();
            }
        } catch (IOException e) {
            e.printStackTrace();
            if (bis!=null) {
                try {
                    bis.close();
                } catch (IOException ee){}
            }
            if (zis!=null) {
                try {
                    zis.close();
                } catch (IOException ee){}
            }
        }
        return list;
    }

}

}

█ 使用

压缩打包文件:

public class ZipUtilTest {

    @Test
    public void testZipFile() {
        try {
            // 读取文件1
            File file1 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip1.text");
            FileInputStream fis1 = new FileInputStream(file1);
            byte[] fileBytes1 = new byte[fis1.available()];
            fis1.read(fileBytes1);

            // 读取文件2
            File file2 = new File("E:\\project\\java\\src\\main\\resources\\zip\\zip2.text");
            FileInputStream fis2 = new FileInputStream(file1);
            byte[] fileBytes2 = new byte[fis2.available()];
            fis2.read(fileBytes2);

            // 获取压缩包文件字节数组
            byte[] bytes = ZipUtil.createZipObject().addFile(fileBytes1, file1.getName()).addFile(fileBytes2, file2.getName()).create();
            
            /**
             * 如果是响应给浏览器的话,可以:
             * HttpServletResponse.getOutputStream().write(bytes[]);
             */
            
            // 将压缩包数据写到本地
            FileOutputStream fos = new FileOutputStream("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
            fos.write(bytes);


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

解压压缩包中的文件:

@Test
public void testUnZipFile() {
    try {
        // 读取压缩文件
        File file = new File("E:\\project\\java\\src\\main\\resources\\zip\\hello.zip");
        FileInputStream fis1 = new FileInputStream(file);
        byte[] fileBytes1 = new byte[fis1.available()];
        fis1.read(fileBytes1);

        ZipUtil.UnZipObject unZipObject = ZipUtil.createUnZipObject(fileBytes1);
        List<ZipEntry> entryList = unZipObject.getEntrys();
        System.out.println("entryList:"+entryList.size());
        entryList.forEach(zipEntry -> {
            try {
                // zipEntry.getName() 压缩包里面的文件名
                FileOutputStream fos = new FileOutputStream("E:\\project\\"+zipEntry.getName());
                // zipEntry.getExtra()是压缩包里面的一个个文件数据
                fos.write(zipEntry.getExtra());
                fos.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        });


    } catch (Exception e) {
        e.printStackTrace();
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java实现压缩解压文件 的相关文章

  • 使用Cloudflare和notion搭建自己的博客

    欢迎访问我的个人博客ximikang icu 使用Cloudflare和notion搭建自己的博客 使用过Nation的小伙伴一定在某个时刻冒出过这样子的想法 这个笔记应用这么好用 而且是基于Web端开发的 那为什么不可以用他来作为我自己的
  • AndroidStudio项目打包成library以及jar包、aar包流程

    引言 一般项目做多了后 码农们都会整理出一系列的工具类来 为了方便在后面项目中使用 打包成library或者jar aar包供项目使用是比较好的方式 1 library方式 library方式是比较简单的方式 一般新建完一个项目的时候 点击
  • 使用JDK开发WebService-客户端建立

    一 序言 上篇 我已经写了一个简单的WebService服务器 看起来貌似不错 但我们真正的目的是想通过编程的方式来访问服务器 而不是通过eclipse带的Web Service浏览器来访问 服务器我们是一行行代码敲出来的 客户端同样我们也
  • hexo博客优化之文章置顶+置顶标签

    本文首发于wangwlj com 博文置顶 一种方法是手动对相关文件进行修改 具体可参考这篇文章 另一种方法就是 目前已经有修改后支持置顶的仓库 可以直接用以下命令安装 npm uninstall hexo generator index
  • 基本数据类型对象包装类

    基本数据类型对象包装类 为了方便操作基本数据类型值 将其封装成了对象 在对象中定义了属性和行为丰富了该数据的操作 用于描述该对象的类就称为基本数据类型包装类 byte Byte short Short int Integer long Lo
  • 简单快速复制CSDN上的博客到自己的电脑上(带图片和格式)

    准备工具 typora md编辑器 直接去官网https www typora io 下载 一直点下一步 下载好了后界面是这样的 清爽且好用 需要做一点设置 文件 偏好设置 图像 如下设置 软件已经安装好并且可以使用了 看到这里可能你会有疑
  • Notion 公开页面关闭右上角的try notion

    问题描述 需要在Notion的公开页面关闭Try Notion 和左边的一堆图标 如果你使用的是Cloudflare自定义域名的那个方法 Jimmy s Writer Life 是可以实现的 只剩下一个切换Dark Light Mode的B
  • Hexo

    前言 搭建博客两个必要条件 博客框架 托管平台 这里框架我们采用Hexo 而平台大部分人会选择GitHub 这里我选择的是Gitee 属于国内的代码托管平台 相比于GitHub来说 访问速度更快 更稳定 环境要求 Git Nodejs 安装
  • 洛谷P1149(NOIP2008) 火柴棒等式 (C语言 + 详细注释)

    题目描述 给你n根火柴棍 你可以拼出多少个形如 A B C 的等式 等式中的A B C是用火柴棍拼出的整数 若该数非零 则最高位不能是00 用火柴棍拼数字0 9的拼法如图所示 注意 加号与等号各自需要两根火柴棍 如果A B 则A B C与B
  • 开源云同步的markdown写作软件——Yosoro

    文章目录 前言 简便的项目管理 舒服的写作体验 支持one driver 存在缺点 前言 Yosoro是一款支持在Win Linux macOS上使用的写作软件 它的界面设计以及交互上表达出的极简主义可以让用户们可以完全沉浸于自己写作世界
  • 利用ScheduledThreadPoolExecutor定时执行任务

    最近时间好忙 终于抽出时间来写一篇博客了 想了想 把之前遇到的一个小bug分享一下吧 之前在做时钟插件时候 我用到了一个定时器 即大家常用的TimerTask 但它总是意外的停止 就是我开启了一个定时器 每一秒都会走run方法 有时候定时器
  • Wordpress入门建站教程二:搭建WP站点的准备工作

    WordPress入门第一课就简单介绍了WordPress 它是一个使用 PHP语言和 MySQL数据库开发的开源 免费的建站程序 那么搭建WordPress站点 就要求一个能够运行PHP语言的主机空间和一个MySQL数据库 也许有些朋友会
  • 我来了,在这里起航

    五一过后 这济南的天全然没有了泉城该有的灵秀 夜里恼人的大风 总是肆无忌惮的闹一晚上 而这忽冷忽热的交替 却是让好些人陷入了穿秋裤脱秋裤的 噩梦 中 别看这几日热的紧 好歹有个晴朗的天空 据说过几日又是大雨倾盆的节奏 这济南的春啊 总是让人
  • Java实现压缩解压文件

    关键词 ZipOutputStream ZipInoutStream 最近在工作中有需求需要在浏览器中一次性下载多个文件 于是想到了使用压缩的功能 百度了一下 发现很多博客的内容都大致相同 不太方便使用 于是自己写了这么一个工具类 使用JD
  • 请用美丽欢呼-------Day38

    周末 双休 疯了两天 敲了寥寥的代码 却没少看了相关的文章 这电子书大行于世的年代 对工具的漠然简直就是对生命的亵渎 颠簸的公交车上算是告别了YY的惬意 这生活 感觉傻了点 可真够味 原本只是想写篇 html的发展历程 的 可XHTML 2
  • Django 快速搭建博客 第三节(数据库表设计)

    上一节我们已经能在pycharm下新建了blog app了 这个时候 我们需要设计一下博客的数据库设计 关于数据库表的设计 作为新手的我们并不需要要求懂太多稍微的懂一些也就可以了 毕竟数据库也是需要有一定的功底的 这里我们依据博客学习 将博
  • service启动失败问题排查

    本文首发在我的个人博客 https jlice top p 7ve9p 欢迎大家前去参观 么么哒 我的电脑在启动时总会提示 Failed to start Load Kernel Modules 虽然不影响使用 可强迫症看了还是会觉得难受
  • 编码问题

    编码 字符 gt 字节数组 解码 字节数组 gt 字符 编码 String str 你好 byte bus str getBytes UTF 8 解码 String str1 new String bus UTF 8 System out
  • 基于Hexo+Matery的LuckyBlog开源搭建教程

    前言 之前在B站上发布了个人博客的视频 播放量也破千了 有网友私聊也想要搭建一个这样的博客 经过一段时间的准备 现将本人博客的源代码公布出来 大家只需要根据以下的步骤 即可快速搭建一个漂亮完善的博客 0x01 LuckyBlog 介绍 上一
  • WordPress主题 响应式个人博客主题Kratos源码

    Kratos 是一款专注于用户阅读体验的响应式 WordPress 主题 整体布局简洁大方 针对资源加载进行了优化 Kratos主题基于Bootstrap和Font Awesome的WordPress一个干净 简单且响应迅速的博客主题 Vt

随机推荐

  • Android平台一对一音视频通话方案对比:WebRTC VS RTMP VS RTSP

    一对一音视频通话使用场景 一对一音视频通话都需要稳定 清晰和流畅 以确保良好的用户体验 常用的使用场景如下 社交应用 社交应用是一种常见的使用场景 用户可以通过音视频通话进行面对面的交流 在线教育 老师和学生可以通过音视频通话功能进行实时互
  • vue 封装一个滚动组件和使用自定义指令封装一个滚动触底触发回调指令(纵向滚动瀑布流)

    方式一 滚动组件 纵向滚动触发触底事件和触顶事件
  • 在传统公司干是一种什么体验(八)

    永远不要相信酒桌上说的话 表哥语录 表哥去了新公司之后 经常参加应酬 因为表哥比较实诚 来者不拒 喝酒特别容易喝多 但是表哥有个好处 喝多了不说话 而且第二天能记住昨晚的事 表哥在酒桌上已经收获了999 客户跟表哥的结拜 999 大BOSS
  • 关于Unity加载优化,你可能会遇到这些问题

    关键词 资源加载 卸载 实例化实例化 资源管理方法 一 资源加载 Q1 Shader 是独立打包的 如果我在开始游戏的时候加载一次 以后切换场景时就不用每次加载了吗 确切地说 要实现后续Shader不加载开销 需要满足以下两个条件 1 包含
  • Sophus安装踩坑

    装SLAM十四讲第二版提供的Sophus Eigen版本3 4 0 报错 home ch 下载 Sophus 13fb3288311485dc94e3226b69c9b59cd06ff94e test core test so2 cpp 9
  • JAVAfx11打包部署

    1 将默认打包工具删除 添加maven shade plugin依赖 如下
  • 有实力的人才能谈梦想

    我总是徘徊 在犹豫 觉得自己做不到 只是在苟延残喘摆了 所谓的目标也不可能实现 今天我发现我做到了 原来也不是那么遥不可及 是自己不够自信 不够淡定 有实力的人聊梦想 没理想的人就想想怎么混工作吧 有实力的人 自信 坚定的毅力 不怕失败 淡
  • Vue.directive指令(自定义指令)

    定义方式 html页面定义 Vue directive hello function el binding vnode el style color binding value 全局定义 Vue directive hello insert
  • 2.搭建Fabric区块链网络环境——前提条件和fabric的安装

    1 安装前提条件 这些前提条件的满足确保了你可以顺利地搭建和运行 Fabric 区块链网络 并进行链码的开发 部署和执行 安装 Docker 确保系统上已经安装了 Docker 并且 Docker 服务正在运行 Docker Fabric
  • [MySQL]MySQL内置函数

    MySQL MySQL内置函数 文章目录 MySQL MySQL内置函数 1 日期函数 2 字符串函数 3 数学函数 4 其他函数 1 日期函数 常用日期函数如下 函数名称 描述 current date 获取当前日期 current ti
  • Trick: QSplashScreen中设置其他控件,并控制其大小

    方案一 使用qss设置控件内容 无法自适应窗口大小 方案二 在代码中通过QFont等类 代码直接设置大小 大小可为变量 窗口跳转时出现控件闪动 大小变动 方案Final 在代码中使用setStyleSheet 设置控件 QFont font
  • css文本输入框的样式

    form control display block width 100 height 34px padding 6px 12px font size 14px line height 1 428571429 color 555555 ve
  • 怎样为std::map的自定义key提供比较操作(一)

    stl的关联容器 map set 的key一般要求提供 lt 比较操作 假设我们有一个结构SomeKey struct SomeKey int a b 要想以SomeKey作为std map的key 需要为这个结构提供operator lt
  • (1)海思Hi3531DV100开发环境搭建

    海思Hi3531DV100开发环境搭建 1 本方案在linkpi开发板Hi3531Dv100上测试 一 安装SDK 1 Hi3531DV100 SDK包位置 在 Hi3531DV100 V100R001 01 software board
  • the resource is not on the build path of a java project错误

    在eclipse中 使用mavenimport了一个工程 但是在对某一个类进行F3 F4 ctrl alt H操作的时候报错 the resource is not on the build path of a java project 这
  • Windows下libcurl的配置(笔记)

    第一步 下载curl源代码 在官网就能下到 第二部 解压文件 进入文件新建一个名为build的目录 在build目录中新建一个install目录用于存放安装文件 第三部 用CMAKE配置 没有可以去下载 第四部 点击Configure之后
  • 前端搭建猜数字游戏(内附源码)

    The sand accumulates to form a pagoda 写在前面 功能介绍 页面搭建 样式设置 逻辑部分 完整代码 写在前面 上周我们实通过前端基础实现了打字通 当然很多伙伴再评论区提出了想法 后续我们会考虑实现的 今天
  • 传值、传址、引用的介绍及各自的优缺点

    1 传值 1 1 概念 void Swap int left int right int temp left left right right temp int main int a 10 int b 20 cout lt lt a lt
  • Angular8 环境搭建

    Angular 环境搭建 无论使用什么前端框架 都必然使用到NodeJS工具 Angular也不例外 Angular采用的是 全家桶 式的设计思路 因此 angular cli脚手架工具集成了日常开发需要使用到的所有NodeJS模块 使用
  • Java实现压缩解压文件

    关键词 ZipOutputStream ZipInoutStream 最近在工作中有需求需要在浏览器中一次性下载多个文件 于是想到了使用压缩的功能 百度了一下 发现很多博客的内容都大致相同 不太方便使用 于是自己写了这么一个工具类 使用JD