您的位置:首页 > 编程语言 > Java开发

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

2014-12-24 16:13 543 查看
2010年做项目的时候偶尔要用到压缩解压目录相关操作,本来以为随便网上搜索一下就有,结果找了半天都没找到,无奈去看下apacheCompress的api,自己写了个。,使用了apache的Compress,common-io。

       有一个比较容易出错的地方,有些压缩方法,如果压缩目录中有空文件夹,可能是解压不出来的,

这是因为压缩的时候,只对于文件写了entryName,文件夹的entryName没有写。

这种情况下,zip文件的entry树结构:大概如下:

Java代码  


+目录A/目录B/目录C/文件1  

  

+目录A/目录B/目录D/文件2  

 

这种解压的时候如果CD层没有另外的目录,结果与正常的压缩方法没区别,层级目录能正常创建。

但是如果有一个E的空目录和在CD同级的情况,解压完不会有E目录

正常的压缩目录应该为

Java代码  


+目录A  

  

+目录A/目录B  

  

+目录A/目录B/目录C  

  

+目录A/目录B/目录D  

  

+目录A/目录B/目录E  

  

+目录A/目录B/目录C/文件1  

  

+目录A/目录B/目录D/文件2  

 

 

附代码:

Java代码  


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

    }  

   

  

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: