2010年做项目的时候偶尔要用到压缩解压目录相关操作,本来以为随便网上搜索一下就有,结果找了半天都没找到,无奈去看下apacheCompress的api,自己写了个。,使用了apache的Compress,common-io。
有一个比较容易出错的地方,有些压缩方法,如果压缩目录中有空文件夹,可能是解压不出来的,
这是因为压缩的时候,只对于文件写了entryName,文件夹的entryName没有写。
这种情况下,zip文件的entry树结构:大概如下:
+目录A/目录B/目录C/文件1 +目录A/目录B/目录D/文件2
这种解压的时候如果CD层没有另外的目录,结果与正常的压缩方法没区别,层级目录能正常创建。
但是如果有一个E的空目录和在CD同级的情况,解压完不会有E目录
正常的压缩目录应该为
+目录A +目录A/目录B +目录A/目录B/目录C +目录A/目录B/目录D +目录A/目录B/目录E +目录A/目录B/目录C/文件1 +目录A/目录B/目录D/文件2
附代码:
public final class ZipTools { private int bufferLen = 1024 * 1024; /** * 私有化构造方法,prevents calls from subclass */ private ZipTools() { throw new UnsupportedOperationException(); } private ZipTools(int bufferLen) { this.bufferLen = bufferLen; } public static ZipTools getInstance() { return new ZipTools(1024 * 1024); } public static ZipTools getInstance(int bufferLen) { return new ZipTools(bufferLen); } /** * 用于单文件压缩 */ protected void doCompress(File srcFile, File destFile) throws IOException { ZipArchiveOutputStream out = null; InputStream is = null; try { is = new BufferedInputStream(new FileInputStream(srcFile), bufferLen); out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(destFile), bufferLen)); ZipArchiveEntry entry = new ZipArchiveEntry(srcFile.getName()); entry.setSize(srcFile.length()); out.putArchiveEntry(entry); IOUtils.copy(is, out); out.closeArchiveEntry(); } finally { IOUtils.closeQuietly(is); IOUtils.closeQuietly(out); } } /** * 解压文件 * @param zipFile * @param outDir * @throws IOException * 90s */ public void doDecompress(String zipFilePath, String outDirStr) throws IOException { File zipFile = new File(zipFilePath); File outDir = new File(outDirStr); ZipArchiveInputStream is = null; try { is = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipFile), bufferLen)); ZipArchiveEntry entry = null; while ((entry = is.getNextZipEntry()) != null) { if (entry.isDirectory()) { File directory = new File(outDir, entry.getName()); directory.mkdirs(); } else { OutputStream os = null; try { os = new BufferedOutputStream(new FileOutputStream(new File(outDir, entry.getName())), bufferLen); IOUtils.copy(is, os); } finally { IOUtils.closeQuietly(os); } } } } finally { IOUtils.closeQuietly(is); } } /** * 解压指定zip文件到目录,使用新方法 * @param outDir 输出到的目录,此目录如果不存在会自动创建 * @param unZipfileName 需要解压的zip文件名 * @throws IOException * 30s */ public static void unZip(String outDirPath, String unZipfilePath) throws IOException { FileOutputStream fileOutStream = null; InputStream inputStream = null; ZipFile zipFile = null; File outDir = new File(outDirPath); File unZipfile = new File(unZipfilePath); if (!unZipfile.exists()) { throw new FileNotFoundException("File to upzip:" + unZipfilePath + " not found!"); } try { zipFile = new ZipFile(unZipfile); Enumeration<?> e = zipFile.getEntries(); while (e.hasMoreElements()) { ZipArchiveEntry entry = (ZipArchiveEntry) e.nextElement(); File file = new File(outDir, entry.getName()); //File file = getRealFileName(outDirPath, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { // 如果指定文件的目录不存在,则创建之. File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } try { inputStream = zipFile.getInputStream(entry); fileOutStream = new FileOutputStream(file); IOUtils.copy(inputStream, fileOutStream); } finally { IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(fileOutStream); } } } } finally { ZipFile.closeQuietly(zipFile); IOUtils.closeQuietly(inputStream); } } /** * 从文件中解压一个指定文件 * @param fileName * @param zipFile * @return * @throws IOException * @throws ZipException */ public InputStream readFileFromSingleFile(ZipFile zipFile, ZipArchiveEntry entry) throws IOException { InputStream inputStream = zipFile.getInputStream(entry); return inputStream; } /** * 把一个目录打包到一个指定的zip文件中 * @param dirStr 目录绝对地址 * @param pathName zip文件内相对结构 * @throws IOException */ private void packFiles(ZipArchiveOutputStream out, File dir, String pathName) throws IOException { InputStream is = null; //返回此绝对路径下的文件 File[] files = dir.listFiles(); if (files == null || files.length < 1) { return; } for (int i = 0; i < files.length; i++) { File zFile = files[i]; out.putArchiveEntry(new ZipArchiveEntry(zFile, pathName + zFile.getName())); //判断此文件是否是一个文件夹 if (zFile.isDirectory()) { packFiles(out, zFile, pathName + zFile.getName() + "/"); } else { try { //out.putArchiveEntry(new ZipArchiveEntry(pathName + files[i].getName())); is = new BufferedInputStream(new FileInputStream(zFile), bufferLen); IOUtils.copy(is, out); } finally { is.close(); } } } } /** * 压缩文件或者文件夹 * @param srcFileStr 待压缩文件或文件夹路径 * @param destFileStr 目标文件路径 * @throws IOException */ public void zip(String srcFileStr, String destFileStr) throws IOException { File destFile = new File(destFileStr); File srcFile = new File(srcFileStr); zip(srcFile, destFile); } /** * 压缩文件 * @param srcFile 待压缩文件或文件夹 * @param destFile目标压缩文件 * @throws IOException */ public void zip(File srcFile, File destFile) throws IOException { ZipArchiveOutputStream out = null; // 如果压缩文件存放目录不存在,则创建之. File pfile = destFile.getParentFile(); if (!pfile.exists()) { pfile.mkdirs(); } //如果是文件 if (srcFile.isFile()) { doCompress(srcFile, destFile); return; } else { try { out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(destFile), bufferLen)); packFiles(out, srcFile, ""); out.closeArchiveEntry(); } finally { IOUtils.closeQuietly(out); } } } /** * 将压缩文件中部分文件压缩到另外一个文件中 */ public void copyEntryToAnother(ZipFile srcFile, File destFile, ArrayList<ZipArchiveEntry> entryList) throws IOException { ZipArchiveOutputStream out = null; FileOutputStream fileOutStream = null; InputStream inputStream = null; //建立临时目录 String tempDirStr = System.getProperty("java.io.tmpdir") + "temp" + File.separatorChar; File tempDir = new File(tempDirStr, String.valueOf(FlowNoGenerator.instance().getFlowNo())); tempDir.mkdirs(); try { //解压 for (ZipArchiveEntry entry : entryList) { File file = new File(tempDir, entry.getName()); if (entry.isDirectory()) { file.mkdirs(); } else { // 如果指定文件的目录不存在,则创建之. File parent = file.getParentFile(); if (!parent.exists()) { parent.mkdirs(); } try { inputStream = srcFile.getInputStream(entry); fileOutStream = new FileOutputStream(file); IOUtils.copy(inputStream, fileOutStream); } finally { IOUtils.closeQuietly(inputStream); IOUtils.closeQuietly(fileOutStream); } } } //压缩 zip(tempDir, destFile); } finally { FileUtils.deleteQuietly(tempDir); } IOUtils.closeQuietly(out); } }
相关推荐
ame()); tOut.putArchiveEntry(tarEntry);...通过引入该库,我们可以轻松地在 Java 程序中实现文件和文件夹的压缩与解压缩功能。在实际开发中,注意错误处理、资源管理以及安全性等方面,以确保程序的健壮性和安全性。
在压缩包子文件的文件名称列表中,我们看到"bce-java-sdk-0.10.31",这很可能是该SDK的一个特定版本号。版本号中的“0.10.31”表明这是SDK的第31个次要更新,在版本控制系统中,通常这种格式表示主版本号、次版本号...
压缩文件方法 该方法需要引用zip4j的jar文件 单个文件、多个文件压缩 /** * 使用给定密码压缩指定文件或文件夹到指定位置. * * dest可传最终压缩文件存放的绝对路径,也...一个简单的demo 欢迎大家指点,一起提升
总结来说,Java提供了解压缩ZIP文件的强大工具,开发者可以通过`java.util.zip`包中的类来实现。`UnZip.java`和`UnZip2.java`文件可能是这种功能的具体实现,通过阅读它们的源代码,可以深入了解Java解压ZIP文件的...
2. **Apache Ant**:`ant-1.10.6.jar`是Apache的一个构建工具,虽然主要用途不是处理Zip文件,但它包含了一些用于文件操作的任务,包括处理Zip文件。 - **压缩任务**:Ant中的`zip`任务可以用于创建Zip文件,你可以...
这篇博客文章《Java压缩解压文件》可能会详细讲解如何使用Java API来处理ZIP文件格式。 在Java中,我们可以利用内置的`java.util.zip`包来处理压缩和解压操作。`ZipOutputStream`和`ZipInputStream`是这个包中的...
4. **写入压缩文件**:压缩后的数据和元数据会被写入到主压缩文件中,形成一个可解压的文件。 5. **添加额外信息**:某些压缩格式允许添加额外的信息,如全局文件头、注释、密码保护等,这些也会被整合到压缩文件中...
在Java编程中,处理压缩和解压缩ZIP文件是一项常见的任务,尤其当文件中包含中文字符时,可能会遇到中文乱码的问题。这是因为Java的标准库在处理非ASCII编码时可能存在不足。本篇文章将详细介绍如何使用Java标准库...
在使用Java对ZIP压缩文件进行解压的方式中有两种,一种是使用apache提供的ant.jar工具包,但是如果ZIP文件中含有中文名称的文件,在解压后,文件名将出现乱码,另一种是使用Java自身JDK中java.util.zip包下工具类,...
本文将详细介绍一个Java方法,该方法用于解压包含多层目录结构的ZIP文件,并能够支持中文文件名。这种方法利用了Apache Ant库中的`org.apache.tools.zip.ZipFile`类来实现解压功能。在实际应用中,这种方法非常实用...
此外,对于大型文件或者需要流式处理的情况,Java的NIO.2(New IO)API提供了FileChannel和MappedByteBuffer等工具,它们能更高效地处理大文件的压缩和解压缩。 总的来说,处理GZ文件需要理解Java的I/O流和压缩库,...
Java zip压缩包查看程序,应用弹出文件选择框,选择ZIP格式的压缩文件,可以像Winrar软件一样查看压缩文件内部的文件及文件夹,源码截图如上所示。 Java 数字签名、数字证书生成源码 2个目标文件 摘要:JAVA源码,...
在批量解压时,上述过程需要在一个循环中进行,遍历所有目标压缩文件。同时,如果压缩包带有密码,需要在创建解压对象时提供。例如,在`uniVocity-rarlib`中,可以通过`RarReaderBuilder`设置密码。 至于`src`和`...
Java 实现文件夹的解压和压缩主要依赖...总的来说,Java 提供的 `java.util.zip` 工具类使得我们可以方便地处理 ZIP 文件格式,无论是压缩还是解压缩文件和文件夹。只需合理使用这些类,即可实现自定义的文件处理逻辑。
在提供的“decompression”这个压缩包子文件的文件名称列表中,我们可以推断这可能是一个包含解压相关代码或者资源的文件夹。具体的内容可能包括各种编程语言的解压示例代码、测试用例、或者是一个已经封装好的解压...
在Java编程中,向现有的ZIP压缩包追加文件通常需要经过解压、修改、再压缩的步骤,因为标准的Java ZIP库(如`java.util.zip`包)并不直接支持追加到已存在的ZIP文件。本篇文章将深入探讨如何实现这个功能,主要关注...
总的来说,Java结合Apache Commons Compress库提供了一个强大且灵活的方式来处理压缩文件,特别是对于包含中文文件名的情况。通过正确设置字符编码,我们可以确保在压缩和解压过程中文件名的完整性和正确性。
在ZipUtil工具类中,我们定义了一个递归压缩方法`zip(ZipOutputStream out, File inputFile, String base, boolean isDelete)`,该方法用于递归地压缩文件夹或者文件。该方法的参数分别是:压缩包输出流、需要压缩的...
在Java中,我们可以使用`java.util.zip`包中的类,如`ZipOutputStream`和`ZipInputStream`来实现文件或目录的压缩与解压。下面将详细介绍这些知识点。 ### 1. `java.util.zip`包 这个包提供了处理多种压缩格式的类...
在Java编程语言中,处理文件和文件夹的压缩与解压是常见的任务,尤其是在需要传输大量数据或存储空间有限的情况下。Zip格式是一种广泛使用的压缩格式,Java提供了内建的API来支持这种格式,使得开发者可以方便地进行...