zoukankan      html  css  js  c++  java
  • java解压缩/压缩/加密压缩/加密解压缩 ZIP4J---ZIP文件压缩与解压缩学习

    最近公司准备让各项目组提供公共工具组件,手中正好无事便研究其中一个工具 - 文件压缩与解压缩工具。

              目前JAVA API已提供对于ZIP文件的压缩与解压缩,但网上总结不支持ZIP文件加密与解密甚至对于中文支持也有问题,于是果断找其他的支持加密解密的第三方包。 winzipaes 与 ZIP4J 都符合项目的要求 ,最终选择ZIP4J来进行使用。

    • ZIP4J 是一个支持处理ZIP文件的开源库
    • 支持创建,修改,添加,删除,解压 压缩文件
    • 支持读/写密码保护
    • 支持AES加密 128/256
    • 支持标准ZIP加密
    • 支持进度监视器
    • 自持Unicode 文件名
    • 支持创建分卷压缩文件
    • 支持将文件添加到压缩包中但不进行压缩


    ZIP4J 项目地址为  :http://www.lingala.net/zip4j/ ,但该地址无法直接访问需要使用代理进行访问

    再提供一个在线代理网站:http://www.7daili.com/

    目前ZIP4J 版本为:1.3.1 ,只需要直接下一载一个zip4j_1.3.1.jar一个jar包即可,同时可以下载官网提供的例子进行学习,例子相当详细(官网提供的例子的jdk 为1.4的版本 导入后需要修改一下)




    官网提供的例子程序比较简单与小巧 整个程序也就一百多k,但demo程序对于各种功能的使用讲的非常详细。

    项目包结构分为三层:

    • ZIP:该包下主要讲述压缩包的新增,修改,删除等例子(包含加密文件创建,通过流的方式创建 、添加压缩文件 、创建分卷压缩文件);
    • MISC:该包下主要展示几个工具方法例子,如:是否是分卷压缩包的判断、获取压缩包中的文件信息(文件名 大小等信息)、压缩进度查看、根据文件名删除压缩包对应文件等;
    • EXTRACT:该包下例子都是关于解压压缩包的例子,包括解压加密文件等;


    示例代码

    示例代码中需要对文件进行操作,为方便程序运行创建以下三个文件 可以直接运行大多数代码

    1. sample.txt
    2. myvideo.avi
    3. mysong.mp3


    示例1 创建压缩包添 加文件到压缩包中(未设置加密)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    public class AddFilesDeflateComp {
          
        public AddFilesDeflateComp() {
            try {
                  
                ZipFile zipFile = new ZipFile("c:\ZipTest\AddFilesDeflateComp.zip");
                  
                ArrayList<File> filesToAdd = new ArrayList<File>();
                filesToAdd.add(new File("c:\ZipTest\sample.txt"));
                filesToAdd.add(new File("c:\ZipTest\myvideo.avi"));
                filesToAdd.add(new File("c:\ZipTest\mysong.mp3"));
                  
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); // set compression method to deflate compression             parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 
                zipFile.addFiles(filesToAdd, parameters);
                  
            } catch (ZipException e) {
                e.printStackTrace();
            }   
        }
          
        /**
         * @param args
         */
        public static void main(String[] args) {
            new AddFilesDeflateComp();
        }
      
    }
    • 该类主要用于创建普通压缩包。如果压缩包不存在 则会自动创建一个ZIP包;如果已经存在一个不为空的同名ZIP压缩包 会将内容添加到该同名压缩包中。
    • 如果手动创建一个格式为ZIP的空压缩包进行保存,则为抛出异常:ZipException :Negative seek offset
    • 如果将其他的文件后缀修改为ZIP包再运行程序,也会抛出异常:ZipException: zip headers not found. probably not a zip file
    • ZIP4J 提供ZipParameters对象来进行压缩参数设置,其中setCompressionMethod方法可以设置压缩还是 不压缩


    示例2 创建压缩包添加文件到 指定目录中进行压缩

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class AddFilesToFolderInZip {
      
        public AddFilesToFolderInZip() {
            try {
                ZipFile zipFile = new ZipFile("c:\ZipTest\AddFilesDeflateComp.zip");
                ArrayList<File> filesToAdd = new ArrayList<File>();
                filesToAdd.add(new File("c:\ZipTest\sample.txt"));
                filesToAdd.add(new File("c:\ZipTest\myvideo.avi"));
                filesToAdd.add(new File("c:\ZipTest\mysong.mp3"));
                  
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
                  
                parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
                parameters.setRootFolderInZip("test2/");
                  
      
                zipFile.addFiles(filesToAdd, parameters);
            } catch (ZipException e) {
                e.printStackTrace();
            
              
              
        }
          
        /**
         * @param args
         */
        public static void main(String[] args) {
            new AddFilesToFolderInZip();
        }
      
    }


    • 该程序执行后,会将sample.txt、myvideo.avi、mysong.mp3 添加到test2文件夹中 并生成AddFilesDeflateComp.zip 压缩包
    • 如果已经存在AddFilesDeflateComp.zip,则会将需要打包的内容添加到已经存在的压缩包去


    示例3 添加文件夹到压缩包中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class AddFolder {
          
        public AddFolder() {
              
            try {
                  
                ZipFile zipFile = new ZipFile("c:\ZipTest\AddFolder.zip");
                String folderToAdd = "c:\FolderToAdd";
              
                ZipParameters parameters = new ZipParameters();
                  
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
                parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
                zipFile.addFolder(folderToAdd, parameters);
                  
            } catch (ZipException e) {
                e.printStackTrace();
            }
        }
          
        public static void main(String[] args) {
            new AddFolder();
        }
          
    }
    • 需要添加的文件夹必须存在,否则抛出异常:ZipException: input folder does not exist
    • * 如果已经存在同名文件则会出现一个文件的时候会出现一个问题,程序会生成一个临时包并去修改之前存在的同名压缩文件,最后修改不成功且会抛出异常:ZipException: cannot rename modified zip file最后只留下一个临时包, 建议在生成的时候添加判断 避免出现这种错误

        

    示例4 创建加密压缩包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    public class AddFilesWithAESEncryption {
          
        public AddFilesWithAESEncryption() {
              
            try {
                ZipFile zipFile = new ZipFile("c:\ZipTest\AddFilesWithAESZipEncryption.zip");
      
                ArrayList<File> filesToAdd = new ArrayList<File>();
                filesToAdd.add(new File("c:\ZipTest\sample.txt"));
                filesToAdd.add(new File("c:\ZipTest\myvideo.avi"));
                filesToAdd.add(new File("c:\ZipTest\mysong.mp3"));
                  
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
                  
                parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 
                parameters.setEncryptFiles(true);
                  
                parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
                  
      
                parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
                parameters.setPassword("123");
          
                zipFile.addFiles(filesToAdd, parameters);
            } catch (ZipException e) {
                e.printStackTrace();
            }
        }
          
        public static void main(String[] args) {
            new AddFilesWithAESEncryption();
        }
          
    }

    加密压缩包后打开时需要输入密码,与rar相同:



    示例5 创建分卷压缩包

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    public class CreateSplitZipFile {
          
        public CreateSplitZipFile() {
              
            try {
              
                ZipFile zipFile = new ZipFile("c:\ZipTest\CreateSplitZipFile.zip");
                  
      
                ArrayList<File> filesToAdd = new ArrayList<File>();
                filesToAdd.add(new File("c:\ZipTest\sample.txt"));
                filesToAdd.add(new File("c:\ZipTest\myvideo.avi"));
                filesToAdd.add(new File("c:\ZipTest\mysong.mp3"));
                  
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
                  
                parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
                  
                zipFile.createZipFile(filesToAdd, parameters, true, 65536);
            } catch (ZipException e) {
                e.printStackTrace();
            }
        }
          
        /**
         * @param args
         */
        public static void main(String[] args) {
            new CreateSplitZipFile();
        }
      
    }
    • 执行程序后会根据设置大小生成多个  压缩包名.z + 数量编号文件,如下图:
    • 如果已经存在同名压缩包,则会抛出异常提示已经存在:ZipException: zip file: c:ipTestCreateSplitZipFile.zip already exists. To add files to existing zip file use addFile method
    • 需要进行分卷压缩的大小,不能小于规定的65536 bytes


    示例6 通过流的方式添加文件到压缩包中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    public class AddStreamToZip {
          
        public AddStreamToZip() {
              
            InputStream is = null;
              
            try {
                ZipFile zipFile = new ZipFile("c:\ZipTest\AddStreamToZip.zip");
      
                ZipParameters parameters = new ZipParameters();
                parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
                parameters.setFileNameInZip("yourfilename.txt");
                parameters.setSourceExternalStream(true);
                  
                is = new FileInputStream("c:\ZipTest\sample.txt");
                zipFile.addStream(is, parameters);
                  
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    try {
                        is.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
          
        public static void main(String[] args) {
            new AddStreamToZip();
              
        }
          
          
    }


    示例7 解压压缩文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class ExtractAllFiles {
          
        public ExtractAllFiles() {
              
            try {
                ZipFile zipFile = new ZipFile("c:\ZipTest\ProgressInformation.zip");
                zipFile.extractAll("c:\ZipTest1");
                  
            } catch (ZipException e) {
                e.printStackTrace();
            }
              
        }
      
        /**
         * @param args
         */
        public static void main(String[] args) {
            new ExtractAllFiles();
        }
      
    }
    • 如果解压的文件需要密码,可以添加以下代码:
    • 1
      2
      3
      4
      if (zipFile.isEncrypted()) {
                      // if yes, then set the password for the zip file                 zipFile.setPassword("test123!");
                  }

    • 在进行解压缩时需要判断文件是否为加密压缩,否则会抛出异常:ZipException: empty or null password provided for AES Decryptor

    压缩效率

       ZIP4J提供5中压缩算法:

    1.     DEFLATE_LEVEL_FASTEST 
    2.     DEFLATE_LEVEL_FASTEST
    3.     DEFLATE_LEVEL_NORMAL
    4.     DEFLATE_LEVEL_MAXIMUM
    5.     DEFLATE_LEVEL_ULTRA

       根据API提供的几种不同压缩级别进行测试(文件夹压缩),测试结果如下:

       一个180M的文件夹压缩后

    •    WinRAR 30秒 - 78.7 MB ; 
    •    NORMAL - 18 秒 91.2 MB  ;
    •    FAST 13秒 -93.1 MB;
    •    FASTEST - 最快速10 秒94.7 MB 
    •    MAXIMUM 23 秒 - 90.7 MB;
    •    ULTRA -50 90.6 MB

        与WinRAR 相比较来说,压缩时间还是很不错 但对文件的压缩大小来说还是WINRAR要强一些 (各人电脑配置不同 压缩的时间这些也不同)


         以上便是ZIP4J提供的一些常用的工具方法,总结在此,方便自己与大家使用。如果有更好的工具或者有不正确的地方欢迎大家指出!


  • 相关阅读:
    leetcode Majority Element
    Missing Number 三种解法
    Effective C++学习笔记 chapter 1
    C++ 笔记
    三色排序
    归并排序-就地排序
    506,display有哪些值?说明他们的作用
    505,display,float,position之间的关系(有疑问)
    504,什么是FOUC?怎么避免
    503,display:none;与visibility:hidden;的区别
  • 原文地址:https://www.cnblogs.com/hzcya1995/p/13318262.html
Copyright © 2011-2022 走看看