• java zip压缩与解压-支持空目录,保留文件修改时间,md5值不会变


    原文:https://www.jb51.cc/java/460346.html

    <dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-compress</artifactId>
    <version>1.20</version>
    </dependency>

    package com.ceadeal.javafxboot.util;
    
    import java.io.BufferedInputStream;
    import java.io.BufferedOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    
    import org.apache.commons.compress.archivers.zip.ZipArchiveEntry;
    import org.apache.commons.compress.archivers.zip.ZipArchiveInputStream;
    import org.apache.commons.compress.archivers.zip.ZipArchiveOutputStream;
    import org.apache.commons.io.IOUtils;
    import org.apache.commons.lang3.StringUtils;
     
    public class ZipFileUtil {
        /**
         * 把一个目录打包到一个指定的zip文件中
         * 
         * @param dirpath
         *            目录路径
         * @param zipPath
         *            zip文件路径
         */
        public static void compressFoldToZip(String dirpath,String zipPath) {
            compressFoldToZip(dirpath,zipPath,"");
        }
        /**
         *  把一个目录打包到一个指定的zip文件中
         * @param dirpath
         * @param zipPath
         * @param entryPath 压缩内文件逻辑路径。如static/
         */
        public static void compressFoldToZip(String dirpath,String zipPath,String entryPath){
            if(!entryPath.endsWith(File.separator)&&StringUtils.isNotBlank(entryPath)){
                entryPath+=File.separator;
            }
            ZipArchiveOutputStream out = null;
            try {
                out = new ZipArchiveOutputStream(new BufferedOutputStream(new FileOutputStream(new File(zipPath))));
                out.setEncoding("UTF-8");
                compressFoldToZip(out,dirpath,entryPath);
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(out);
            }
        }
        /**
         * 把一个目录打包到一个指定的zip文件中
         * 
         * @param out
         * @param dirpath
         *            目录路径
         * @param entryPath
         *            zip中文件的逻辑路径
         */
        private static void compressFoldToZip(ZipArchiveOutputStream out,String dirpath,String entryPath) {
            InputStream ins = null;
            File dir = new File(dirpath);
            File[] files = dir.listFiles();
            if (files == null || files.length < 1) {
                return;
            }
            try {
                for (int i = 0; i < files.length; i++) {
                    // 判断此文件是否是一个文件夹
                    if (files[i].isDirectory()) {
                        if(files[i].listFiles().length>0){
                            compressFoldToZip(out,files[i].getAbsolutePath(),entryPath + files[i].getName() + File.separator);
                        }else{
                            addFileToZip(files[i],out,entryPath);
                        }
                    } else {
                        addFileToZip(files[i], out, entryPath);
                    }
                }
                out.flush();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(ins);
            }
        }
     
        private static void addFileToZip(File file,ZipArchiveOutputStream out,String entryPath) {
            InputStream ins = null;
            try {
                
                String path=entryPath + file.getName();
                if(file.isDirectory()){
                    path=formatDirPath(path); //为了在压缩文件中包含空文件夹
                }
                ZipArchiveEntry entry = new ZipArchiveEntry(path);
                entry.setTime(file.lastModified());
                // entry.setSize(files[i].length());
                out.putArchiveEntry(entry);
                if(!file.isDirectory()){
                    ins = new BufferedInputStream(new FileInputStream(file.getAbsolutePath()));
                    IOUtils.copy(ins,out);
                }
                out.closeArchiveEntry();
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(ins);
            }
        }
     
        /**
         * 解压zip文件到指定目录
         * 
         * @param zipPath
         * @param destDir
         */
        public static void unZipToFold(String zipPath,String destDir) {
            ZipArchiveInputStream ins = null;
            OutputStream os = null;
            File zip = new File(zipPath);
            if (!zip.exists()) {
                return;
            }
            File dest = new File(destDir);
            if (!dest.exists()) {
                dest.mkdirs();
            }
            destDir=formatDirPath(destDir);
            try {
                ins = new ZipArchiveInputStream(new BufferedInputStream(new FileInputStream(zipPath)),"UTF-8");
                ZipArchiveEntry entry = null;
                while ((entry = ins.getNextZipEntry()) != null) {
                    if (entry.isDirectory()) {
                        File directory = new File(destDir,entry.getName());
                        directory.mkdirs();
                        directory.setLastModified(entry.getTime());
                    } else {
                        String absPath=formatPath(destDir+entry.getName());
                        mkdirsForFile(absPath);
                        File tmpFile=new File(absPath);
                        os=new BufferedOutputStream(new FileOutputStream(tmpFile));
                        IOUtils.copy(ins,os);
                        IOUtils.closeQuietly(os);
                        tmpFile.setLastModified(entry.getTime());
                    }
                }
     
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                IOUtils.closeQuietly(ins);
            }
        }
        private static String formatPath(String path){
            path=path.replace('\',File.separatorChar);
            path=path.replace('/',File.separatorChar);
            return path;
        }
        private static String formatDirPath(String dir){
            if(!dir.endsWith(File.separator)){
                dir+=File.separator;
            }
            return dir;
        }
        private static void mkdirsForFile(String filePath){
            String absPath=filePath;
            String tmpPath=absPath.substring(0,absPath.lastIndexOf(File.separator));
            File tmp=new File(tmpPath);
            if(!tmp.exists()){
                tmp.mkdirs();
            }
        }
        public static void main(String[] args) {
            long start = System.currentTimeMillis();
            compressFoldToZip("D:\abc2","D:\abc2.zip");
    //        unZipToFold("D:\abc11.zip","D:\abc2");
            long end = System.currentTimeMillis();
            System.out.println((end - start) + "ms");
        }
    }
  • 相关阅读:
    PHP 求多个数组的笛卡尔积,适用于求商品规格组合 【递归思想, 类似广度优先搜索】【原创】
    CCF推荐期刊会议
    SCI分区
    值和指针接收者的区别
    程序员练级攻略
    保险
    golang 有缓冲channel和无缓冲channel
    后台学习路线
    golang之反射
    atomic和mutex
  • 原文地址:https://www.cnblogs.com/shihaiming/p/13447647.html
Copyright © 2020-2023  润新知