zoukankan      html  css  js  c++  java
  • 使用java API进行zip递归压缩文件夹以及解压

    一、概述

    在本篇文章中,给大家介绍一下如何将文件进行zip压缩以及如何对zip包解压。所有这些都是使用Java提供的核心库java.util.zip来实现的。

    二、压缩文件

    首先我们来学习一个简单的例子-压缩单个文件。将一个名为test1.txt的文件压缩到一个名为Compressed.zip的zip文件中。

    public class ZipFile {
        public static void main(String[] args) throws IOException {
           
            //输出压缩包
            FileOutputStream fos = new FileOutputStream("src/main/resources/compressed.zip");
            ZipOutputStream zipOut = new ZipOutputStream(fos);
    
            //被压缩文件
            File fileToZip = new File("src/main/resources/test1.txt");
            FileInputStream fis = new FileInputStream(fileToZip);
            
            //向压缩包中添加文件
            ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
            zipOut.putNextEntry(zipEntry);
            byte[] bytes = new byte[1024];
            int length;
            while((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes, 0, length);
            }
            zipOut.close();
            fis.close();
            fos.close();
        }
    }
    

    三、压缩多个文件

    接下来,我们看看如何将多个文件压缩为一个zip文件。我们将把test1.txttest2.txt压缩成multiCompressed.zip

    public class ZipMultipleFiles {
        public static void main(String[] args) throws IOException {
            List<String> srcFiles = Arrays.asList("src/main/resources/test1.txt", "src/main/resources/test2.txt");
            FileOutputStream fos = new FileOutputStream("src/main/resources/multiCompressed.zip");
            ZipOutputStream zipOut = new ZipOutputStream(fos);
            //向压缩包中添加多个文件
            for (String srcFile : srcFiles) {
                File fileToZip = new File(srcFile);
                FileInputStream fis = new FileInputStream(fileToZip);
                ZipEntry zipEntry = new ZipEntry(fileToZip.getName());
                zipOut.putNextEntry(zipEntry);
     
                byte[] bytes = new byte[1024];
                int length;
                while((length = fis.read(bytes)) >= 0) {
                    zipOut.write(bytes, 0, length);
                }
                fis.close();
            }
            zipOut.close();
            fos.close();
        }
    }
    

    四、压缩目录

    下面的例子,我们将zipTest目录及该目录下的递归子目录文件,全都压缩到dirCompressed.zip中

    public class ZipDirectory {
        public static void main(String[] args) throws IOException, FileNotFoundException {
            //被压缩的文件夹
            String sourceFile = "src/main/resources/zipTest"; 
            //压缩结果输出,即压缩包
            FileOutputStream fos = new FileOutputStream("src/main/resources/dirCompressed.zip");
            ZipOutputStream zipOut = new ZipOutputStream(fos);
            File fileToZip = new File(sourceFile);
            //递归压缩文件夹
            zipFile(fileToZip, fileToZip.getName(), zipOut);
            //关闭输出流
            zipOut.close();
            fos.close();
        }
         
    
        /**
         * 将fileToZip文件夹及其子目录文件递归压缩到zip文件中
         * @param fileToZip 递归当前处理对象,可能是文件夹,也可能是文件
         * @param fileName fileToZip文件或文件夹名称
         * @param zipOut 压缩文件输出流
         * @throws IOException
         */
        private static void zipFile(File fileToZip, String fileName, ZipOutputStream zipOut) throws IOException {
            //不压缩隐藏文件夹
            if (fileToZip.isHidden()) {
                return;
            }
            //判断压缩对象如果是一个文件夹
            if (fileToZip.isDirectory()) {
                if (fileName.endsWith("/")) {
                    //如果文件夹是以“/”结尾,将文件夹作为压缩箱放入zipOut压缩输出流
                    zipOut.putNextEntry(new ZipEntry(fileName));
                    zipOut.closeEntry();
                } else {
                    //如果文件夹不是以“/”结尾,将文件夹结尾加上“/”之后作为压缩箱放入zipOut压缩输出流
                    zipOut.putNextEntry(new ZipEntry(fileName + "/"));
                    zipOut.closeEntry();
                }
                //遍历文件夹子目录,进行递归的zipFile
                File[] children = fileToZip.listFiles();
                for (File childFile : children) {
                    zipFile(childFile, fileName + "/" + childFile.getName(), zipOut);
                }
                //如果当前递归对象是文件夹,加入ZipEntry之后就返回
                return;
            }
            //如果当前的fileToZip不是一个文件夹,是一个文件,将其以字节码形式压缩到压缩包里面
            FileInputStream fis = new FileInputStream(fileToZip);
            ZipEntry zipEntry = new ZipEntry(fileName);
            zipOut.putNextEntry(zipEntry);
            byte[] bytes = new byte[1024];
            int length;
            while ((length = fis.read(bytes)) >= 0) {
                zipOut.write(bytes, 0, length);
            }
            fis.close();
        }
    }
    
    • 要压缩子目录及其子目录文件,所以需要递归遍历
    • 每次遍历找到的是目录时,我们都将其名称附加“/”,并将其以ZipEntry保存到压缩包中,从而保持压缩的目录结构。
    • 每次遍历找到的是文件时,将其以字节码形式压缩到压缩包里面

    五、解压缩zip压缩包

    下面为大家举例讲解解压缩zip压缩包。在此示例中,我们将compressed.zip解压缩到名为unzipTest的新文件夹中。

    public class UnzipFile {
        public static void main(String[] args) throws IOException {
            //被解压的压缩文件
            String fileZip = "src/main/resources/unzipTest/compressed.zip";
            //解压的目标目录
            File destDir = new File("src/main/resources/unzipTest");
    
            byte[] buffer = new byte[1024];
            ZipInputStream zis = new ZipInputStream(new FileInputStream(fileZip));
            //获取压缩包中的entry,并将其解压
            ZipEntry zipEntry = zis.getNextEntry();
            while (zipEntry != null) {
                File newFile = newFile(destDir, zipEntry);
                FileOutputStream fos = new FileOutputStream(newFile);
                int len;
                while ((len = zis.read(buffer)) > 0) {
                    fos.write(buffer, 0, len);
                }
                fos.close();
                //解压完成一个entry,再解压下一个
                zipEntry = zis.getNextEntry();
            }
            zis.closeEntry();
            zis.close();
        }
        //在解压目标文件夹,新建一个文件
        public static File newFile(File destinationDir, ZipEntry zipEntry) throws IOException {
            File destFile = new File(destinationDir, zipEntry.getName());
    
            String destDirPath = destinationDir.getCanonicalPath();
            String destFilePath = destFile.getCanonicalPath();
    
            if (!destFilePath.startsWith(destDirPath + File.separator)) {
                throw new IOException("该解压项在目标文件夹之外: " + zipEntry.getName());
            }
    
            return destFile;
        }
    }
    

    欢迎关注我的博客,里面有很多精品合集

    • 本文转载注明出处(必须带连接,不能只转文字):字母哥博客

    觉得对您有帮助的话,帮我点赞、分享!您的支持是我不竭的创作动力! 。另外,笔者最近一段时间输出了如下的精品内容,期待您的关注。

  • 相关阅读:
    How to create jar for Android Library Project
    Very large tabs in eclipse panes on Ubuntu
    64bit Ubuntu, Android AAPT, R.java
    Linux(Ubuntu)下如何安装JDK
    Configure xterm Fonts and Colors for Your Eyeball
    建立、配置和使用Activity——启动其他Activity并返回结果
    建立、配置和使用Activity——使用Bundle在Activity之间交换数据
    建立、配置和使用Activity——启动、关闭Activity
    建立、配置和使用Activity——Activity
    异步任务(AsyncTask)
  • 原文地址:https://www.cnblogs.com/zimug/p/13467639.html
Copyright © 2011-2022 走看看