Zip和7-zip谁更强,如何选择?

麦洛 等级 602 0 0

Zip和7-zip谁更强,如何选择?

一. 7z rar zip之间的区别

7z一般对应的软件是7zip
zip对应的是winzip
rar对应的 winrar
只不过现在这几个软件基本互相支持。
7z压缩比率大些。zip次之,压缩比率越大,压缩的越小哦!!!

zip格式比较常见,支持泛围广。windows操作系统不装任选第三方软件也可以打开zip格式。
rar 和7z必须用解压缩软件才行。

二 使用jdk操作winzip文件解压缩

我们使用jdk自带的zip解决方案来测试winzip文件解压缩

Zip和7-zip谁更强,如何选择?

2.1 压缩zip文件

    /**
     * 压缩zip文件
     * @param sourceFilePath
     * @param zipFilePath
     * @param fileName
     * @return
     */
    public static String zip(String sourceFilePath, String zipFilePath, String fileName) {
        File                sourceFile = new File(sourceFilePath);
        FileInputStream     fis;
        BufferedInputStream bis        = null;
        FileOutputStream    fos;
        ZipOutputStream     zos        = null;
        if (!sourceFile.exists()) {
            System.out.println("待压缩的文件目录:" + sourceFilePath + "不存在.");
        } else {
            try {
                File zipFile = new File(zipFilePath + File.separator + fileName + ".zip");
                if (zipFile.exists()) {
                    System.out.println(zipFilePath + "目录下存在名字为:" + fileName + ".zip" + "打包文件.");
                } else {
                    File[] sourceFiles = sourceFile.listFiles();
                    if (null == sourceFiles || sourceFiles.length < 1) {
                        System.out.println("待压缩的文件目录:" + sourceFilePath + "里面不存在文件,无需压缩.");
                    } else {
                        fos = new FileOutputStream(zipFile);
                        zos = new ZipOutputStream(new BufferedOutputStream(fos));
                        byte[] bufs = new byte[1024 * 10];
                        for (File file : sourceFiles) {
                            //创建ZIP实体,并添加进压缩包
                            ZipEntry zipEntry = new ZipEntry(file.getName());
                            zos.putNextEntry(zipEntry);
                            //读取待压缩的文件并写进压缩包里
                            fis = new FileInputStream(file);
                            bis = new BufferedInputStream(fis, 1024 * 10);
                            int read = 0;
                            while ((read = bis.read(bufs, 0, 1024 * 10)) != -1) {
                                zos.write(bufs, 0, read);
                            }
                        }
                    }
                }
                return zipFile.getAbsolutePath();
            } catch (IOException e) {
                e.printStackTrace();
                return null;
            } finally {
                //关闭流
                try {
                    if (null != bis) bis.close();
                    if (null != zos) zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

测试一下:

    public static void main(String[] args) {
        //压缩文件
        zip("E:\\excel", "E:\\excel", "excel");
    }

我需要压缩的目录 Zip和7-zip谁更强,如何选择?

压缩后的结果:

Zip和7-zip谁更强,如何选择?

2.2 解压zip文件

    /**
     * zip解压文件
     *
     * @param zipFilePath        压缩文件
     * @param unzipFilePath      解压文件路径
     * @param includeZipFileName 是否包含原文件名
     */
    public static String unZip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception {
        if (StringUtils.isBlank(zipFilePath) || StringUtils.isBlank(unzipFilePath)) {
            log.info("-> 必传参数为空");
            return null;
        }
        File zipFile = new File(zipFilePath);
        if (!zipFile.exists() || !zipFile.isFile()) {
            log.info("-> 要解压的文件不存在");
            return null;
        }
        log.info("-> 解压的文件大小: {}", zipFile.length());
        //如果解压后的文件保存路径包含压缩文件的文件名,则追加该文件名到解压路径_
        if (includeZipFileName) {
            String fileName = zipFile.getName();
            log.info("-> fileName: {}", fileName);
            if (!fileName.isEmpty()) {
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
                log.info("-> fileName: {}", fileName);
            }
            unzipFilePath = unzipFilePath + File.separator + fileName;
        }
        log.info("-> unzipFilePath: {}", unzipFilePath);
        //创建解压缩文件保存的路径
        File unzipFileDir = new File(unzipFilePath);
        if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
            boolean crtDir = unzipFileDir.mkdirs();
            log.info("-> 创建存储解压后的路径{}", crtDir);
        }
        //开始解压
        ZipEntry                        entry;
        String                          entryFilePath, entryDirPath;
        File                            entryFile, entryDir;
        int                             index, count, bufferSize = 1024;
        byte[]                          buffer                   = new byte[bufferSize];
        BufferedInputStream             bis;
        BufferedOutputStream            bos;
        ZipFile                         zip                      = new ZipFile(zipFile, Charset.forName("gbk"));
        Enumeration<? extends ZipEntry> entries                  = zip.entries();
        //循环对压缩包里的每一个文件进行解压
        while (entries.hasMoreElements()) {
            entry = new ZipEntry(entries.nextElement());
            //构建压缩包中一个文件解压后保存的文件全路径
            entryFilePath = unzipFilePath + File.separator + entry.getName();
            fileFullNames.add(entryFilePath);
            entryDir = new File(entryFilePath);
            //如果文件夹路径不存在,则创建文件夹
            if (!(entryDir.exists() && entryDir.isDirectory())) {
                entryDir.mkdirs();
            }

            //创建解压文件
            entryFile = new File(entryFilePath);
            if (entryFile.exists()) {
                //删除已存在的目标文件
                entryFile.delete();
            }
            //写入文件
            bos = new BufferedOutputStream(new FileOutputStream(entryFile));
            bis = new BufferedInputStream(zip.getInputStream(entry));
            while ((count = bis.read(buffer, 0, bufferSize)) != -1) {
                bos.write(buffer, 0, count);
            }
            bos.flush();
            bos.close();

            bis.close();
        }
        return unzipFilePath;
    }

解压测试

    public static void main(String[] args) {
        //解压文件
        try {
            unZip("E:\\excel\\excel.zip", "E:\\excel\\jy", false);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

解压前:

Zip和7-zip谁更强,如何选择?

解压后: Zip和7-zip谁更强,如何选择?

三 使用commons-compress操作7zip文件解压缩

这里,我们使用apache-commons-compress软件库来进行7zip文件的解压缩

Zip和7-zip谁更强,如何选择?

Apache Commons Compress库定义了一个用于处理ar,cpio,Unix转储,tar,zip,gzip,XZ,Pack200,bzip2、7z,arj,lzma,snappy,DEFLATE,lz4,Brotli,Zstandard,DEFLATE64和Z文件的API 。

此组件中的代码有很多渊源:

  • 对bzip2,tar和zip的支持来自Avalon的Excalibur,但就Apache的生存而言,其最初来自Ant。tar包最初是Tim Endres的公共领域包。bzip2软件包基于Keiron Liddle和Julian Seward的 libbzip2所做的工作。它已通过以下方式迁移: Ant-> Avalon-Excalibur-> Commons-IO-> Commons-Compress。
  • cpio软件包由Michael Kuss和jRPM 项目贡献。

3.1 maven依赖

        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-compress</artifactId>
            <version>1.9</version>
        </dependency>

3.2 压缩7zip文件

    /**
     * 7z文件压缩
     *
     * @param sourceFilePath  待压缩目录路径
     * @param zipFilePath 生成的压缩包路径
     * @param fileName 生成的压缩包目录
     */

    public static void compress7zip(String sourceFilePath, String zipFilePath, String fileName) throws Exception {
        File input = new File(sourceFilePath);
        if (!input.exists()) {
            throw new Exception(input.getPath() + "待压缩文件不存在");
        }
        SevenZOutputFile out = new SevenZOutputFile(new File(zipFilePath));

        compress(out, input, fileName);
        out.close();
    }

        /**
     * @param fileName 压缩文件名,可以写为null保持默认
     */
    //递归压缩
    public static void compress(SevenZOutputFile out, File input, String fileName) throws IOException {

        SevenZArchiveEntry entry = null;
        //如果路径为目录(文件夹)
        if (input.isDirectory()) {
            //取出文件夹中的文件(或子文件夹)
            File[] flist = input.listFiles();

            if (flist.length == 0)//如果文件夹为空,则只需在目的地.7z文件中写入一个目录进入
            {
                /*entry = out.createArchiveEntry(input,name + "/");
                out.putArchiveEntry(entry);*/
            } else//如果文件夹不为空,则递归调用compress,文件夹中的每一个文件(或文件夹)进行压缩
            {
                for (int i = 0; i < flist.length; i++) {
                    compress(out, flist[i], fileName + "/" + flist[i].getName());
                }
            }
        } else//如果不是目录(文件夹),即为文件,则先写入目录进入点,之后将文件写入7z文件中
        {
            FileInputStream fos = new FileInputStream(input);
            BufferedInputStream bis = new BufferedInputStream(fos);
            entry = out.createArchiveEntry(input, fileName);
            out.putArchiveEntry(entry);
            int len = -1;
            //将源文件写入到7z文件中
            byte[] buf = new byte[1024];
            while ((len = bis.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            bis.close();
            fos.close();
            out.closeArchiveEntry();
        }
    }

3.3 解压7zip文件

    /**
     * 7Zzip解压文件
     *
     * @param zipFilePath        压缩文件
     * @param unzipFilePath      解压文件路径
     * @param includeZipFileName 是否包含原文件名
     */
    public static String un7zZip(String zipFilePath, String unzipFilePath, boolean includeZipFileName) throws Exception {
        if (StringUtils.isBlank(zipFilePath) || StringUtils.isBlank(unzipFilePath)) {
            log.info("-> 必传参数为空");
            return null;
        }
        File zipFile = new File(zipFilePath);
        if (!zipFile.exists() || !zipFile.isFile()) {
            log.info("-> 要解压的文件不存在");
            return null;
        }
        log.info("-> 解压的文件大小: {}", zipFile.length());
        //如果解压后的文件保存路径包含压缩文件的文件名,则追加该文件名到解压路径_
        if (includeZipFileName) {
            String fileName = zipFile.getName();
            log.info("-> fileName: {}", fileName);
            if (!fileName.isEmpty()) {
                fileName = fileName.substring(0, fileName.lastIndexOf("."));
                log.info("-> fileName: {}", fileName);
            }
            unzipFilePath = unzipFilePath + File.separator + fileName;
        }
        log.info("-> unzipFilePath: {}", unzipFilePath);
        //创建解压缩文件保存的路径
        File unzipFileDir = new File(unzipFilePath);
        if (!unzipFileDir.exists() || !unzipFileDir.isDirectory()) {
            boolean crtDir = unzipFileDir.mkdirs();
            log.info("-> 创建存储解压后的路径{}", crtDir);
        }
        //开始解压
        String                          entryFilePath, entryDirPath;
        SevenZFile zIn = new SevenZFile(zipFile);
        SevenZArchiveEntry entry = null;
        File file = null;

        StringJoiner fileFullNames = new StringJoiner(",");
        while ((entry = zIn.getNextEntry()) != null) {
            if (!entry.isDirectory()) {
                //构建压缩包中一个文件解压后保存的文件全路径
                entryFilePath = unzipFilePath + File.separator + entry.getName();
                //日志
                fileFullNames.add(entryFilePath);


                file = new File(entryFilePath);
                if (!file.exists()) {
                    new File(file.getParent()).mkdirs();//创建此文件的上级目录
                }

                //写文件
                OutputStream out = new FileOutputStream(file);
                BufferedOutputStream bos = new BufferedOutputStream(out);
                int len = -1;
                byte[] buf = new byte[1024];
                while ((len = zIn.read(buf)) != -1) {
                    bos.write(buf, 0, len);
                }
                // 关流顺序,先打开的后关闭
                bos.close();
                out.close();
            }
        }
        log.info("-> 解压成功: {}", fileFullNames.toString());
        return unzipFilePath;
    }

四 zip和7zip压缩结果比对

4.1 zip压缩

Zip和7-zip谁更强,如何选择?

4.2 7zip压缩

Zip和7-zip谁更强,如何选择?

从结果来看,7z压缩方式压缩比更高,生成文件越小,感觉可能文件越大,效果越明显,如果只针对于我本次测试而言,我发现7z的压缩方式相对zip来说,速度慢很多,所以如果是小文件操作,还是推荐zip

五 Zip4j

这里推荐一款操作zip的明星库Zip4j,非常的方便好用,也是我同事推荐给我的!!!!

5.1 Zip4j介绍

Zip4j是用于zip文件或流的最全面的Java库。在撰写本文时,除其他一些功能外,它是唯一支持zip加密的Java库。它试图使处理zip文件/流变得更加容易。输入流和输出流不再笨拙的样板代码。正如你可以在下面的用法部分中看到,与zip文件的工作,现在即使是一个单一的代码行,比起这个。我的意思是不破坏Java的内置zip支持。实际上,该库依赖于Java的内置邮政编码,并且它本来应该更多。复杂如果我还必须编写压缩逻辑,那就很有挑战性。但老实说,使用zip文件或流可能是很多样板代码。该库的主要目的是通过在库中进行繁重的工作来为zip文件或流的所有常规操作提供一个简单的API,而不必让开发人员担心必须处理流等。

5.2 Zip4j特性

  • 创建,添加,提取,更新,从zip文件中删除文件
  • 支持流(ZipInputStream和ZipOutputStream)
  • 读/写受密码保护的zip文件和流
  • 支持AES和zip标准加密方法
  • 支持Zip64格式
  • 存储(无压缩)和放气压缩方法
  • 从拆分的zip文件创建或提取文件(例如:z01,z02,... zip)
  • 支持Unicode中的Unicode文件名和注释
  • 进度监视器-用于集成到应用程序和面向用户的应用程序中

5.3 功能演示

package com.milo.zip;

import net.lingala.zip4j.ZipFile;
import net.lingala.zip4j.exception.ZipException;
import net.lingala.zip4j.model.ZipParameters;
import net.lingala.zip4j.model.enums.AesKeyStrength;
import net.lingala.zip4j.model.enums.EncryptionMethod;
import org.junit.Test;

import java.io.File;
import java.util.Arrays;
import java.util.List;

/**
 * @author Milo Lee
 * @date 2020-12-28 15:47
 */
public class ZipTest {

    /**
     *创建zip文件,包含单个文件
     */
    @Test
    public void test1(){
        try {
            //方式一
            new ZipFile("F:\\电子书\\milolee.zip").addFile("F:\\电子书\\Head First Java 中文高清版.pdf");
            //方式二
            new ZipFile("F:\\电子书\\milolee.zip").addFile(new File("F:\\电子书\\Head First Java 中文高清版.pdf"));
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建zip文件,包含多个文件
     */
    @Test
    public void test2(){
        try {
            new ZipFile("F:\\电子书\\milolee.zip").addFiles(Arrays.asList(new File("F:\\电子书\\Head First Java 中文高清版.pdf"),
                    new File("F:\\电子书\\Spring源码深度解析.pdf")));
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

    /**
     * 创建受密码保护的zip文件
     */
    @Test
    public void test3(){
        ZipParameters zipParameters = new ZipParameters();
        zipParameters.setEncryptFiles(true);
        zipParameters.setEncryptionMethod(EncryptionMethod.AES);
        // Below line is optional. AES 256 is used by default. You can override it to use AES 128. AES 192 is supported only for extracting.
        zipParameters.setAesKeyStrength(AesKeyStrength.KEY_STRENGTH_256);

        List<File> filesToAdd = Arrays.asList(
                new File("F:\\电子书\\Head First Java 中文高清版.pdf"),
                new File("F:\\电子书\\Spring源码深度解析.pdf")
        );

        ZipFile zipFile = new ZipFile("F:\\电子书\\milolee.zip", "milolee".toCharArray());
        try {
            zipFile.addFiles(filesToAdd, zipParameters);
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解压zip
     */
    @Test
    public void test4(){
        try {
            new ZipFile("F:\\电子书\\milolee.zip").extractAll("F:\\电子书\\jy");
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }

    /**
     * 解压一个受密码保护的zip文件
     */
    @Test
    public void test5(){
        try {
            new ZipFile("F:\\电子书\\milolee.zip", "milolee".toCharArray()).extractAll("F:\\电子书\\jy");
        } catch (ZipException e) {
            e.printStackTrace();
        }
    }
}

更多功能,大家可以在github上面找到示例,自己动手测试

收藏
评论区

相关推荐

Zip和7-zip谁更强,如何选择?
Zip和7zip谁更强,如何选择? 一. 7z rar zip之间的区别 mysql 7z一般对应的软件是7zip zip对应的是winzip rar对应的 winrar 只不过现在这几个软件基本互相支持。 7z压缩比率大些。zip次之,压缩比率越大,压缩的越小哦 zip格式比较常见,支持泛围广。windows操作系统不装任选第三方软件也
深入理解 Go Slice
(https://imghelloworld.osscnbeijing.aliyuncs.com/0ce8a8773a658d4b843e5796a0dbf001.png) image 原文地址:深入理解 Go Slice(https://github.com/EDDYCJY/blog/blob/master/golang/pkg/20
Android Service 流程分析
启动Service过程 Android Service启动时序图 (https://imghelloworld.osscnbeijing.aliyuncs.com/039313fdaaf1e7dea3bde222b3ec9934.png) Android Service启动时序图.png 上图就是Android
JavaScript中本地存储的方式有哪些?
(https://imghelloworld.osscnbeijing.aliyuncs.com/1f907f0895e2be23aa56604dd42e3626.png) 一、方式 javaScript本地缓存的方法我们主要讲述以下四种: cookie sessionStorage loc
Pandas案例精进 | 结构化数据非等值范围查找 ②
(https://imghelloworld.osscnbeijing.aliyuncs.com/4971fbce1ecb759123ecc666f3af2c31.png) 大家好,我是小五🐶 欢迎来到「Pandas案例精进」专栏(https://mp.weixin.qq.com/mp/appmsgalbum?__bizMzU5Nzg
30个前端开发人员必备的顶级工具
在本文中,我为前端Web开发人员汇总了30种顶级工具,从代码编辑器和代码游乐场到CSS生成器,JS库等等。 (https://imghelloworld.osscnbeijing.aliyuncs.com/2e7966318084a45d05a0926cbd749a02.png) 目录 CSS代码生成器 CSS3 Generator
SQL 诞生 48年了!为什么我们仍在使用它?
(https://imghelloworld.osscnbeijing.aliyuncs.com/a784e838a6d497b87a19798716e69fe8.png) 为什么我们仍在使用 SQL? SQL 和关系数据库管理系统(RDBMS)都是在 上世纪70 年代早期开发的。Edgar F. Codd 开发了 RDBMS,而 Do
Ubuntu 20.04 常见文件解压 (实用)
第一类 处理 .zip或 .rar 时,需要先下载相对应的unzip和unrar,可在终端,执行 sudo aptget install unzip sudo aptget install unrar .zip unzip .zip .rar unrar x .rar 第二类 .tar
Java的文件压缩-Zip格式
language/ 文件压缩 /public class ZipFileCompress public static void main(String[] args) throws IOException File file new File("E:\\aaa\\web01"); String savePath
mysql基础入门_thankszmy的博客
一、MYSQL 安装下载完后,我们将 zip 包解压到相应的目录,这里我将解压后的文件夹放在 C:\\web\\mysql8.0.15winx64 下。打开刚刚解压的文件夹 C:\\web\\mysql8.0.15winx64,在该文件夹下创建 my.ini 配置文件,编辑 my.ini 配置以下基本信息: [mysql] 设置mysql客户端默认字符集
zip压缩包——加密破解篇
写在前面 前几天在某个 CTF 的交流群想看看大佬们都在聊什么,偶然间看到有人发了一个 pdf (就是这篇文章),一开始顺手点下载下来没怎么看,过几天打开看了一下发现写得挺好的,这篇文章应该是一个大佬的博客里的文章,但是尝试去找到大佬的博客地址却一直没有找到,很遗憾 QAQ 伪加密、爆破、明文攻击和CRC32碰撞+ zip 文件格式: zip 文件由三部分
程序员怎样写出搞垮公司的代码?
1、乱写注释 注释就像内裤,外面看不见,但是很重要。 注释要严谨,不能有明显的漏洞。如果你的内裤有漏洞,你不尴尬吗?当然了,如果你实力够强大,别人会尴尬。 2、代码和显示不一致 界面上是Post code,代码里是Zip code。看代码看到怀疑人生! 所以说年轻人,你只看到了第二层,你以为我在第一层,实际上我在第五层,你明白我在讲什么吗?
MongoDB的安装与基本操作
最近刚好在学习爬虫,了解到MongoDB 非常适合 JSON 数据存储,受到广大爬虫程序员的青睐,故学习之。 一、安装MongoDB官网:进入官网后选择你需要的版本,系统,已及你想要的安装包(可选msi或zip,这里我使用msi,双击安装,简单!)::: warning 在 MongoDB 2.2 版本后已经不再支持 Windows XP 系统。最新版本也
手把手教你用Python破解加密 zip 文件的密码
摄影:产品经理海鲜咖喱泡饭 之前在家里的老电脑中,发现一个加密zip压缩包,由于时隔太久忘记密码了,依稀记得密码是6位字母加数字,网上下载了很多破解密码的软件都没有效果,于是想到自己用Python写一个暴力破解密码的脚本。 Python有一个内置模块zipfile可以干这个事情,测试一波,一个测试文件,设置解压密码为123。import zipfile
Java的文件解压-Zip格式
language / 作者认为解压缩最安全的方法 先创建所有的文件夹 之后创建再文件 <p 原因:未处理好当压缩文件夹下第一个是一个文件夹,考虑到存在有文件可以没有(.)等这些标识符,无法识别出是否是文件夹还是文件, 故根据zipEntry.getName后续返回值是否存在后续文件夹即(\\符号)判断是否其是文件夹,进而可以创建出压缩包下所有的