`

原-Java压缩解压文件、文件夹的一个工具类

 
阅读更多

        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);
    }
 

}

 

分享到:
评论

相关推荐

    使用Java API进行tar.gz文件及文件夹压缩解压缩.docx

    ame()); tOut.putArchiveEntry(tarEntry);...通过引入该库,我们可以轻松地在 Java 程序中实现文件和文件夹的压缩与解压缩功能。在实际开发中,注意错误处理、资源管理以及安全性等方面,以确保程序的健壮性和安全性。

    bce-java-sdk

    在压缩包子文件的文件名称列表中,我们看到"bce-java-sdk-0.10.31",这很可能是该SDK的一个特定版本号。版本号中的“0.10.31”表明这是SDK的第31个次要更新,在版本控制系统中,通常这种格式表示主版本号、次版本号...

    java压缩文件生成带密码的zip包,解压带密码的zip包的工具类

    压缩文件方法 该方法需要引用zip4j的jar文件 单个文件、多个文件压缩 /** * 使用给定密码压缩指定文件或文件夹到指定位置. * * dest可传最终压缩文件存放的绝对路径,也...一个简单的demo 欢迎大家指点,一起提升

    java解压zip压缩文件

    总结来说,Java提供了解压缩ZIP文件的强大工具,开发者可以通过`java.util.zip`包中的类来实现。`UnZip.java`和`UnZip2.java`文件可能是这种功能的具体实现,通过阅读它们的源代码,可以深入了解Java解压ZIP文件的...

    java 操作Zip文件(压缩、解压、加密).zip

    2. **Apache Ant**:`ant-1.10.6.jar`是Apache的一个构建工具,虽然主要用途不是处理Zip文件,但它包含了一些用于文件操作的任务,包括处理Zip文件。 - **压缩任务**:Ant中的`zip`任务可以用于创建Zip文件,你可以...

    Java压缩解压文件

    这篇博客文章《Java压缩解压文件》可能会详细讲解如何使用Java API来处理ZIP文件格式。 在Java中,我们可以利用内置的`java.util.zip`包来处理压缩和解压操作。`ZipOutputStream`和`ZipInputStream`是这个包中的...

    支持多文件及文件夹压缩工具

    4. **写入压缩文件**:压缩后的数据和元数据会被写入到主压缩文件中,形成一个可解压的文件。 5. **添加额外信息**:某些压缩格式允许添加额外的信息,如全局文件头、注释、密码保护等,这些也会被整合到压缩文件中...

    java zip压缩解压工具解决中文乱码问题

    在Java编程中,处理压缩和解压缩ZIP文件是一项常见的任务,尤其当文件中包含中文字符时,可能会遇到中文乱码的问题。这是因为Java的标准库在处理非ASCII编码时可能存在不足。本篇文章将详细介绍如何使用Java标准库...

    解压zip压缩文件,支持多文件目录解压,中文乱码问题

    在使用Java对ZIP压缩文件进行解压的方式中有两种,一种是使用apache提供的ant.jar工具包,但是如果ZIP文件中含有中文名称的文件,在解压后,文件名将出现乱码,另一种是使用Java自身JDK中java.util.zip包下工具类,...

    JAVA解压ZIP多层目录文件(需ant.jar

    本文将详细介绍一个Java方法,该方法用于解压包含多层目录结构的ZIP文件,并能够支持中文文件名。这种方法利用了Apache Ant库中的`org.apache.tools.zip.ZipFile`类来实现解压功能。在实际应用中,这种方法非常实用...

    java压缩+解压GZ(Linux)文件.rar

    此外,对于大型文件或者需要流式处理的情况,Java的NIO.2(New IO)API提供了FileChannel和MappedByteBuffer等工具,它们能更高效地处理大文件的压缩和解压缩。 总的来说,处理GZ文件需要理解Java的I/O流和压缩库,...

    java源码包---java 源码 大量 实例

     Java zip压缩包查看程序,应用弹出文件选择框,选择ZIP格式的压缩文件,可以像Winrar软件一样查看压缩文件内部的文件及文件夹,源码截图如上所示。 Java 数字签名、数字证书生成源码 2个目标文件 摘要:JAVA源码,...

    java实现批量解压带密码的 rar or zip 文件

    在批量解压时,上述过程需要在一个循环中进行,遍历所有目标压缩文件。同时,如果压缩包带有密码,需要在创建解压对象时提供。例如,在`uniVocity-rarlib`中,可以通过`RarReaderBuilder`设置密码。 至于`src`和`...

    java实现文件夹的解压和压缩

    Java 实现文件夹的解压和压缩主要依赖...总的来说,Java 提供的 `java.util.zip` 工具类使得我们可以方便地处理 ZIP 文件格式,无论是压缩还是解压缩文件和文件夹。只需合理使用这些类,即可实现自定义的文件处理逻辑。

    解压gz工具类

    在提供的“decompression”这个压缩包子文件的文件名称列表中,我们可以推断这可能是一个包含解压相关代码或者资源的文件夹。具体的内容可能包括各种编程语言的解压示例代码、测试用例、或者是一个已经封装好的解压...

    基于Java向zip压缩包追加文件

    在Java编程中,向现有的ZIP压缩包追加文件通常需要经过解压、修改、再压缩的步骤,因为标准的Java ZIP库(如`java.util.zip`包)并不直接支持追加到已存在的ZIP文件。本篇文章将深入探讨如何实现这个功能,主要关注...

    java做的压缩解压文件

    总的来说,Java结合Apache Commons Compress库提供了一个强大且灵活的方式来处理压缩文件,特别是对于包含中文文件名的情况。通过正确设置字符编码,我们可以确保在压缩和解压过程中文件名的完整性和正确性。

    Java实现的zip压缩及解压缩工具类示例

    在ZipUtil工具类中,我们定义了一个递归压缩方法`zip(ZipOutputStream out, File inputFile, String base, boolean isDelete)`,该方法用于递归地压缩文件夹或者文件。该方法的参数分别是:压缩包输出流、需要压缩的...

    java zip 压缩解压例子

    在Java中,我们可以使用`java.util.zip`包中的类,如`ZipOutputStream`和`ZipInputStream`来实现文件或目录的压缩与解压。下面将详细介绍这些知识点。 ### 1. `java.util.zip`包 这个包提供了处理多种压缩格式的类...

    Java Zip压缩:简化文件和文件夹的压缩操作

    在Java编程语言中,处理文件和文件夹的压缩与解压是常见的任务,尤其是在需要传输大量数据或存储空间有限的情况下。Zip格式是一种广泛使用的压缩格式,Java提供了内建的API来支持这种格式,使得开发者可以方便地进行...

Global site tag (gtag.js) - Google Analytics