使用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.txt和test2.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; } }
总结
到此这篇关于使用java API实现zip递归压缩文件夹及解压的文章就介绍到这了,更多相关java API实现zip递归压缩文件夹及解压内容请搜索猪先飞以前的文章或继续浏览下面的相关文章希望大家以后多多支持猪先飞!
相关文章
- 这篇文章主要介绍了如何利用java语言实现经典《复杂迷宫》游戏,文中采用了swing技术进行了界面化处理,感兴趣的小伙伴可以动手试一试...2022-02-01
java 运行报错has been compiled by a more recent version of the Java Runtime
java 运行报错has been compiled by a more recent version of the Java Runtime (class file version 54.0)...2021-04-01- 这篇文章主要介绍了在java中获取List集合中最大的日期时间操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要用实例讲解C#递归算法的概念以及用法,文中代码非常详细,帮助大家更好的参考和学习,感兴趣的朋友可以了解下...2020-06-25
- 这篇文章主要介绍了教你怎么用Java获取国家法定节假日,文中有非常详细的代码示例,对正在学习java的小伙伴们有非常好的帮助,需要的朋友可以参考下...2021-04-23
- 这篇文章主要介绍了Java如何发起http请求的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-03-31
- 说起C#和Java这两门语言(语法,数据类型 等),个人以为,大概有90%以上的相似,甚至可以认为几乎一样。但是在工作中,我也发现了一些细微的差别...2020-06-25
- 这篇文章主要介绍了解决Java处理HTTP请求超时的问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-29
- 这篇文章主要介绍了java 判断两个时间段是否重叠的案例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-15
- 这篇文章主要介绍了WebStorm无法正确识别Vue3组合式API的解决方案,帮助大家更好的理解和学习使用vue框架,感兴趣的朋友可以了解下...2021-02-18
- 这篇文章主要介绍了超简洁java实现双色球若干注随机号码生成(实例代码),本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-04-02
java 画pdf用itext调整表格宽度、自定义各个列宽的方法
这篇文章主要介绍了java 画pdf用itext调整表格宽度、自定义各个列宽的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-01-31- 这篇文章主要介绍了Java生成随机姓名、性别和年龄的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-10-01
- 这篇文章主要介绍了浅谈vue2的$refs在vue3组合式API中的替代方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2021-04-18
- 这篇文章主要介绍了java正则表达式判断前端参数修改表中另一个字段的值,需要的朋友可以参考下...2021-05-07
Java使用ScriptEngine动态执行代码(附Java几种动态执行代码比较)
这篇文章主要介绍了Java使用ScriptEngine动态执行代码,并且分享Java几种动态执行代码比较,需要的朋友可以参考下...2021-04-15- 这篇文章主要介绍了Java开发实现人机猜拳游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2020-08-03
- 这篇文章主要介绍了Java List集合返回值去掉中括号('[ ]')的操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-29
Java中lombok的@Builder注解的解析与简单使用详解
这篇文章主要介绍了Java中lombok的@Builder注解的解析与简单使用,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2021-01-06- 下面小编就为大家带来一篇java中String类型变量的赋值问题介绍。小编觉得挺不错的。现在分享给大家,给大家一个参考。...2016-03-28