热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java压缩解压缩

目录一.压缩为zip1.压缩多个文件2.压缩目录二.zip解压缩三.压缩为tar.gz1.压缩多个文件2.压缩目录四.tar.gz解压缩一.压缩为zip使用Java提供的核心库,j

目录

  • 一.压缩为zip
    • 1.压缩多个文件
    • 2.压缩目录
  • 二.zip解压缩
  • 三.压缩为tar.gz
    • 1.压缩多个文件
    • 2.压缩目录
  • 四.tar.gz解压缩


一.压缩为zip

使用Java提供的核心库,java.util.zip


1.压缩多个文件

public class ZipMultipleFiles {public static void main(String[] args) throws IOException {// 文件所在的路径List<String> srcFiles &#61; Arrays.asList("src/main/resources/test1.txt", "src/main/resources/test2.txt");// 构造压缩文件对象FileOutputStream fos &#61; new FileOutputStream("src/main/resources/multiCompressed.zip");ZipOutputStream zipOut &#61; new ZipOutputStream(fos);// 向压缩包对象中添加多个文件for (String srcFile : srcFiles) {File fileToZip &#61; new File(srcFile);ZipEntry zipEntry &#61; new ZipEntry(fileToZip.getName());zipOut.putNextEntry(zipEntry);FileInputStream fis &#61; new FileInputStream(fileToZip);byte[] bytes &#61; new byte[1024];int length;while((length &#61; fis.read(bytes)) >&#61; 0) {// 将文件信息写入压缩文件中zipOut.write(bytes, 0, length);}fis.close();}zipOut.close();fos.close();}
}

2.压缩目录


  • 要压缩子目录及其子目录文件&#xff0c;所以需要递归遍历
  • 每次遍历找到的是目录时&#xff0c;我们都将其名称附加“/”,并将其以ZipEntry保存到压缩包中&#xff0c;从而保持压缩的目录结构。
  • 每次遍历找到的是文件时&#xff0c;将其以字节码形式压缩到压缩包里面

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

二.zip解压缩

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

三.压缩为tar.gz

java中没有一种官方的API可以去创建tar.gz文件。所以我们需要使用到第三方库Apache Commons Compress去创建.tar.gz文件。

  1. tar文件准确的说是打包文件&#xff0c;将文件打包到一个tar文件中&#xff0c;文件名后缀是.tar
  2. Gzip是将文件的存储空间压缩保存&#xff0c;文件名后缀是.gz
  3. tar.gz.tgz通常是指将文件打包到一个tar文件中&#xff0c;并将它使用Gzip进行压缩。

maven坐标

<dependency><groupId>org.apache.commonsgroupId><artifactId>commons-compressartifactId><version>1.20version>
dependency>

1.压缩多个文件

import org.apache.commons.compress.archivers.tar.TarArchiveEntry;
import org.apache.commons.compress.archivers.tar.TarArchiveOutputStream;
import org.apache.commons.compress.compressors.gzip.GzipCompressorOutputStream;
import org.junit.jupiter.api.Test;import java.io.BufferedOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.List;public class TarGzTest {&#64;Testvoid testFilesTarGzip() throws IOException {// 输入文件&#xff0c;被压缩文件Path path1 &#61; Paths.get("/home/test/file-a.xml");Path path2 &#61; Paths.get("/home/test/file-b.txt");List<Path> paths &#61; Arrays.asList(path1, path2);//输出文件压缩结果Path output &#61; Paths.get("/home/test/output.tar.gz");// OutputStream输出流、BufferedOutputStream缓冲输出流// GzipCompressorOutputStream是gzip压缩输出流// TarArchiveOutputStream打tar包输出流&#xff08;包含gzip压缩输出流&#xff09;try (OutputStream fOut &#61; Files.newOutputStream(output);BufferedOutputStream buffOut &#61; new BufferedOutputStream(fOut);GzipCompressorOutputStream gzOut &#61; new GzipCompressorOutputStream(buffOut);TarArchiveOutputStream tOut &#61; new TarArchiveOutputStream(gzOut)) {// 遍历文件listfor (Path path : paths) {// 该文件不是目录或者符号链接if (!Files.isRegularFile(path)) {throw new IOException("Support only file!");}// 将该文件放入tar包&#xff0c;并执行gzip压缩TarArchiveEntry tarEntry &#61; new TarArchiveEntry(path.toFile(),path.getFileName().toString());tOut.putArchiveEntry(tarEntry);Files.copy(path, tOut);tOut.closeArchiveEntry();}// for循环完成之后&#xff0c;finish-tar包输出流tOut.finish();}}
}

2.压缩目录

&#64;Test
void testDirTarGzip() throws IOException {// 被压缩打包的文件夹Path source &#61; Paths.get("/home/test");// 如果不是文件夹抛出异常if (!Files.isDirectory(source)) {throw new IOException("请指定一个文件夹");}// 压缩之后的输出文件名称String tarFileName &#61; "/home/" &#43; source.getFileName().toString() &#43; ".tar.gz";// OutputStream输出流、BufferedOutputStream缓冲输出流// GzipCompressorOutputStream是gzip压缩输出流// TarArchiveOutputStream打tar包输出流&#xff08;包含gzip压缩输出流&#xff09;try (OutputStream fOut &#61; Files.newOutputStream(Paths.get(tarFileName));BufferedOutputStream buffOut &#61; new BufferedOutputStream(fOut);GzipCompressorOutputStream gzOut &#61; new GzipCompressorOutputStream(buffOut);TarArchiveOutputStream tOut &#61; new TarArchiveOutputStream(gzOut)) {// 遍历文件目录树Files.walkFileTree(source, new SimpleFileVisitor<Path>() {//当成功访问到一个文件&#64;Overridepublic FileVisitResult visitFile(Path file,BasicFileAttributes attributes) throws IOException {// 判断当前遍历文件是不是符号链接(快捷方式)&#xff0c;不做打包压缩处理if (attributes.isSymbolicLink()) {return FileVisitResult.CONTINUE;}// 获取当前遍历文件名称Path targetFile &#61; source.relativize(file);// 将该文件打包压缩TarArchiveEntry tarEntry &#61; new TarArchiveEntry(file.toFile(), targetFile.toString());tOut.putArchiveEntry(tarEntry);Files.copy(file, tOut);tOut.closeArchiveEntry();// 继续下一个遍历文件处理return FileVisitResult.CONTINUE;}// 当前遍历文件访问失败&#64;Overridepublic FileVisitResult visitFileFailed(Path file, IOException exc) {System.err.printf("无法对该文件压缩打包为tar.gz : %s%n%s%n", file, exc);return FileVisitResult.CONTINUE;}});// for循环完成之后&#xff0c;finish-tar包输出流tOut.finish();}
}

四.tar.gz解压缩

&#64;Test
public void testDeCompressTarGzip() throws IOException {// 解压文件Path source &#61; Paths.get("/home/test/output.tar.gz");// 解压到哪Path target &#61; Paths.get("/home/test2");if (Files.notExists(source)) {throw new IOException("您要解压的文件不存在");}// InputStream输入流&#xff0c;以下四个流将tar.gz读取到内存并操作// BufferedInputStream缓冲输入流// GzipCompressorInputStream解压输入流// TarArchiveInputStream解tar包输入流try (InputStream fi &#61; Files.newInputStream(source);BufferedInputStream bi &#61; new BufferedInputStream(fi);GzipCompressorInputStream gzi &#61; new GzipCompressorInputStream(bi);TarArchiveInputStream ti &#61; new TarArchiveInputStream(gzi)) {ArchiveEntry entry;while ((entry &#61; ti.getNextEntry()) !&#61; null) {// 获取解压文件目录&#xff0c;并判断文件是否损坏Path newPath &#61; zipSlipProtect(entry, target);if (entry.isDirectory()) {// 创建解压文件目录Files.createDirectories(newPath);} else {// 再次校验解压文件目录是否存在Path parent &#61; newPath.getParent();if (parent !&#61; null) {if (Files.notExists(parent)) {Files.createDirectories(parent);}}// 将解压文件输入到TarArchiveInputStream&#xff0c;输出到磁盘newPath目录Files.copy(ti, newPath, StandardCopyOption.REPLACE_EXISTING);}}}
}// 判断压缩文件是否被损坏&#xff0c;并返回该文件的解压目录
private Path zipSlipProtect(ArchiveEntry entry,Path targetDir)throws IOException {Path targetDirResolved &#61; targetDir.resolve(entry.getName());Path normalizePath &#61; targetDirResolved.normalize();if (!normalizePath.startsWith(targetDir)) {throw new IOException("压缩文件已被损坏: " &#43; entry.getName());}return normalizePath;
}

转载自:
1.http://www.zimug.com/java/%e4%bd%bf%e7%94%a8java-api%e8%bf%9b%e8%a1%8czip%e9%80%92%e5%bd%92%e5%8e%8b%e7%bc%a9%e6%96%87%e4%bb%b6%e5%a4%b9%e4%bb%a5%e5%8f%8a%e8%a7%a3%e5%8e%8b/.html
2.http://www.zimug.com/java/%e4%bd%bf%e7%94%a8java-api%e8%bf%9b%e8%a1%8ctar-gz%e6%96%87%e4%bb%b6%e5%8f%8a%e6%96%87%e4%bb%b6%e5%a4%b9%e5%8e%8b%e7%bc%a9%e8%a7%a3%e5%8e%8b%e7%bc%a9/.html


推荐阅读
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • 本文介绍了Swing组件的用法,重点讲解了图标接口的定义和创建方法。图标接口用来将图标与各种组件相关联,可以是简单的绘画或使用磁盘上的GIF格式图像。文章详细介绍了图标接口的属性和绘制方法,并给出了一个菱形图标的实现示例。该示例可以配置图标的尺寸、颜色和填充状态。 ... [详细]
  • Java SE从入门到放弃(三)的逻辑运算符详解
    本文详细介绍了Java SE中的逻辑运算符,包括逻辑运算符的操作和运算结果,以及与运算符的不同之处。通过代码演示,展示了逻辑运算符的使用方法和注意事项。文章以Java SE从入门到放弃(三)为背景,对逻辑运算符进行了深入的解析。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文整理了Java面试中常见的问题及相关概念的解析,包括HashMap中为什么重写equals还要重写hashcode、map的分类和常见情况、final关键字的用法、Synchronized和lock的区别、volatile的介绍、Syncronized锁的作用、构造函数和构造函数重载的概念、方法覆盖和方法重载的区别、反射获取和设置对象私有字段的值的方法、通过反射创建对象的方式以及内部类的详解。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 从零学Java(10)之方法详解,喷打野你真的没我6!
    本文介绍了从零学Java系列中的第10篇文章,详解了Java中的方法。同时讨论了打野过程中喷打野的影响,以及金色打野刀对经济的增加和线上队友经济的影响。指出喷打野会导致线上经济的消减和影响队伍的团结。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • 本文介绍了在Windows环境下如何配置php+apache环境,包括下载php7和apache2.4、安装vc2015运行时环境、启动php7和apache2.4等步骤。希望对需要搭建php7环境的读者有一定的参考价值。摘要长度为169字。 ... [详细]
  • 本文讨论了在手机移动端如何使用HTML5和JavaScript实现视频上传并压缩视频质量,或者降低手机摄像头拍摄质量的问题。作者指出HTML5和JavaScript无法直接压缩视频,只能通过将视频传送到服务器端由后端进行压缩。对于控制相机拍摄质量,只有使用JAVA编写Android客户端才能实现压缩。此外,作者还解释了在交作业时使用zip格式压缩包导致CSS文件和图片音乐丢失的原因,并提供了解决方法。最后,作者还介绍了一个用于处理图片的类,可以实现图片剪裁处理和生成缩略图的功能。 ... [详细]
  • 第四章高阶函数(参数传递、高阶函数、lambda表达式)(python进阶)的讲解和应用
    本文主要讲解了第四章高阶函数(参数传递、高阶函数、lambda表达式)的相关知识,包括函数参数传递机制和赋值机制、引用传递的概念和应用、默认参数的定义和使用等内容。同时介绍了高阶函数和lambda表达式的概念,并给出了一些实例代码进行演示。对于想要进一步提升python编程能力的读者来说,本文将是一个不错的学习资料。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 微信官方授权及获取OpenId的方法,服务器通过SpringBoot实现
    主要步骤:前端获取到code(wx.login),传入服务器服务器通过参数AppID和AppSecret访问官方接口,获取到OpenId ... [详细]
author-avatar
航模特异_831
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有