Java如何实现压缩文件与解压缩zip文件

 更新时间:2022年12月12日 09:27:30   作者:yujkss  
这篇文章主要介绍了Java如何实现压缩文件与解压缩zip文件问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

Java压缩文件与解压缩zip文件

在日常的使用中经常会使用到像WinRAR或WinZIP这样的压缩文件,通过这些软件可以把一个很大的文件进行压缩以方便传输。

在JAVA中 为了减少传输时的数据量也提供了专门的压缩流,可以将文件或文件夹压缩成ZIP、JAR、GZIP等文件的格式。

ZIP是一种较为常见的压缩形式,在Java中要想实现ZIP的压缩需要导入java.util.zip包,可以使用此包中的ZipFile、ZipOutputStream、ZipInputStream、ZipEntry几个类完成。

testZip

package com.kuang.zip;

import org.apache.commons.io.IOUtils;

import java.io.*;
import java.util.Enumeration;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;

public class testZip {


    public static void unZipIt(String file, String outputFolder) throws IOException {

        ZipFile zipFile = null;
        InputStream in=null;
        OutputStream out=null;
        try {
            zipFile = new ZipFile(file);
            Enumeration <? extends ZipEntry>  entries = zipFile.entries();
            while (entries.hasMoreElements()) {
                ZipEntry entry = entries.nextElement();
                File entryDestination = new File(outputFolder, entry.getName());
                if (entry.isDirectory()) {
                    entryDestination.mkdirs();
                } else {
                    entryDestination.getParentFile().mkdirs();
                    try {
                        out = new FileOutputStream(entryDestination);
                        in = zipFile.getInputStream(entry);
                        IOUtils.copy(in, out);
                    } catch (IOException e) {
                        throw e;
                    }finally {
                        IOUtils.closeQuietly(in);
                        IOUtils.closeQuietly(out);
                    }
                }
            }
        } finally {
            try {
                if(zipFile!=null){zipFile.close();zipFile=null;}
            } catch (IOException e) {
            }
        }
    }

    public static void main(String[] args) throws Exception {

        unZipIt("D:\\Test\\TestbyYTT.zip","D:\\Test\\");

    }

}

org.apache.commons.io.IOUtils需引入maven依赖

<!-- https://mvnrepository.com/artifact/commons-io/commons-io -->
<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.4</version>
</dependency>

org.apache.commons.io.IOUtils.closeQuietly()只是确保流会被关闭,无论流是否正常结束,看源码发现closeQuietly它会忽略异常


那么为什么IOUtils.closeQuietly()会在2.6的时候将它标记为过时呢?

因为Java7里的try-with-resource语法糖的出现,之前定义在try catch外部的流移到了try后边的括号里,不再需要手动关闭了,它会自行处理。

public static void readAll() {
    try (
        FileReader fileReader = new FileReader("test");
        BufferedReader bufferedReader = new BufferedReader(fileReader)
    ) {
        String line;

        while ((line = bufferedReader.readLine()) != null) {
            System.out.println(line);
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
}

拓展:还有一种语法叫multi-catch 可以简化多个catch

FileZip

package com.kuang.zip;

import java.io.*;
import java.util.zip.*;
import java.util.zip.ZipEntry;


public class FileZip {
    /**
     * zip文件压缩
     * @param inputFile 待压缩文件夹/文件名
     * @param outputFile 生成的压缩包名字
     */

    public static void ZipCompress(String inputFile, String outputFile) throws Exception {
        //创建zip输出流
        ZipOutputStream out = new ZipOutputStream(new FileOutputStream(outputFile));
        //创建缓冲输出流
        BufferedOutputStream bos = new BufferedOutputStream(out);
        File input = new File(inputFile);
        compress(out, bos, input,null);
        bos.close();
        out.close();
    }
    /**
     * @param name 压缩文件名,可以写为null保持默认
     */
    //递归压缩
    public static void compress(ZipOutputStream out, BufferedOutputStream bos, File input, String name) throws IOException {
        if (name == null) {
            name = input.getName();
        }
        //如果路径为目录(文件夹)
        if (input.isDirectory()) {
            //取出文件夹中的文件(或子文件夹)
            File[] flist = input.listFiles();

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

    /**
     * zip解压
     * @param inputFile 待解压文件名
     * @param destDirPath  解压路径
     */

    public static void ZipUncompress(String inputFile,String destDirPath) throws Exception {
        File srcFile = new File(inputFile);//获取当前压缩文件
        // 判断源文件是否存在
        if (!srcFile.exists()) {
            throw new Exception(srcFile.getPath() + "所指文件不存在");
        }
        //开始解压
        //构建解压输入流
        ZipInputStream zIn = new ZipInputStream(new FileInputStream(srcFile));
        ZipEntry entry = null;
        File file = null;
        while ((entry = zIn.getNextEntry()) != null) {
            if (!entry.isDirectory()) {
                file = new File(destDirPath, entry.getName());
                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();
            }
        }
    }


    public static void main(String[] args) {
        try {

            ZipCompress("D:\\Test", "D:\\Test\\TestbyYTT.zip");
            ZipUncompress("D:\\Test\\TestbyYTT.zip","D:\\Test\\TestbyYTT的解压文件");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • UniApp + SpringBoot 实现支付宝支付和退款功能

    UniApp + SpringBoot 实现支付宝支付和退款功能

    这篇文章主要介绍了UniApp + SpringBoot 实现支付宝支付和退款功能,基本的 SpringBoot 的脚手架,可以去IDEA 自带的快速生成脚手架插件,本文通过实例代码给大家介绍的非常详细,需要的朋友参考下吧
    2022-06-06
  • 关于Spring Cache 缓存拦截器( CacheInterceptor)

    关于Spring Cache 缓存拦截器( CacheInterceptor)

    这篇文章主要介绍了关于Spring Cache缓存拦截器( CacheInterceptor),具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Spring security如何重写Filter实现json登录

    Spring security如何重写Filter实现json登录

    这篇文章主要介绍了Spring security 如何重写Filter实现json登录,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • struts2入门介绍及代码实例

    struts2入门介绍及代码实例

    这篇文章主要介绍了struts2入门介绍及代码实例,具有一定借鉴价值,需要的朋友可以参考下。
    2017-12-12
  • java中flatMap用法完整示例

    java中flatMap用法完整示例

    flatMap是java8的Stream流的一个方法,下面这篇文章主要给大家介绍了关于java中flatMap用法的相关资料,文中通过示例代码和图文介绍的非常详细,需要的朋友可以参考下
    2023-05-05
  • 详解多云架构下的JAVA微服务技术解析

    详解多云架构下的JAVA微服务技术解析

    本文介绍了基于开源自建和适配云厂商开发框架两种构建多云架构的思路,以及这些思路的优缺点
    2021-05-05
  • shiro多验证登录代码实例及问题解决

    shiro多验证登录代码实例及问题解决

    这篇文章主要介绍了shiro多验证登录代码实例及问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • 关于Object中equals方法和hashCode方法判断的分析

    关于Object中equals方法和hashCode方法判断的分析

    今天小编就为大家分享一篇关于关于Object中equals方法和hashCode方法判断的分析,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Java实现Map遍历key-value的四种方法

    Java实现Map遍历key-value的四种方法

    本文主要介绍了Java实现Map遍历key-value的四种方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Java java.lang.ExceptionInInitializerError 错误如何解决

    Java java.lang.ExceptionInInitializerError 错误如何解决

    这篇文章主要介绍了 Java java.lang.ExceptionInInitializerError 错误如何解决的相关资料,需要的朋友可以参考下
    2017-06-06

最新评论