zoukankan      html  css  js  c++  java
  • java 压缩成zip文件、解压zip文件(可设置密码)

    1.情景展示

      java实现将文件夹进行压缩打包的功能及在线解压功能

    2.解决方案

      方式一:压缩、解压zip

      准备工作:slf4j-api.jar

    <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    

      如果不需要日志记录,则可以把log去掉。

      导入

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.charset.Charset;
    import java.util.Enumeration;
    import java.util.zip.ZipEntry;
    import java.util.zip.ZipFile;
    import java.util.zip.ZipOutputStream;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    

      压缩成zip

    /**
     * 文件压缩、解压工具类
     */
    public class ZipUtils {
    	private static final int BUFFER_SIZE = 2 * 1024;
    	/**
    	 * 是否保留原来的目录结构
    	 * true:  保留目录结构;
    	 * false: 所有文件跑到压缩包根目录下(注意:不保留目录结构可能会出现同名文件,会压缩失败)
    	 */
    	private static final boolean KeepDirStructure = true;
    	private static final Logger log = LoggerFactory.getLogger(ZipUtils.class);
    	public static void main(String[] args) {
    		try {
    //			toZip("D:\apache-maven-3.5.3\maven中央仓库-jar下载", "D:\apache-maven-3.5.3\maven中央仓库-jar下载.zip",true);
    			unZipFiles("D:\\apache-maven-3.5.3\\maven中央仓库-jar下载.zip","D:\apache-maven-3.5.3\maven中央仓库-jar下载");
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    	}
    	
    	/**
    	 * 压缩成ZIP
    	 * @param srcDir         压缩 文件/文件夹 路径
    	 * @param outPathFile    压缩 文件/文件夹 输出路径+文件名 D:/xx.zip
    	 * @param isDelSrcFile   是否删除原文件: 压缩前文件
    	 */
    	public static void toZip(String srcDir, String outPathFile,boolean isDelSrcFile) throws Exception {
    		long start = System.currentTimeMillis();
    		FileOutputStream out = null; 
    		ZipOutputStream zos = null;
    		try {
    			out = new FileOutputStream(new File(outPathFile));
    			zos = new ZipOutputStream(out);
    			File sourceFile = new File(srcDir);
    			if(!sourceFile.exists()){
    				throw new Exception("需压缩文件或者文件夹不存在");
    			}
    			compress(sourceFile, zos, sourceFile.getName());
    			if(isDelSrcFile){
    				delDir(srcDir);
    			}
    			log.info("原文件:{}. 压缩到:{}完成. 是否删除原文件:{}. 耗时:{}ms. ",srcDir,outPathFile,isDelSrcFile,System.currentTimeMillis()-start);
    		} catch (Exception e) {
    			log.error("zip error from ZipUtils: {}. ",e.getMessage());
    			throw new Exception("zip error from ZipUtils");
    		} finally {
    			try {
    				if (zos != null) {zos.close();}
    				if (out != null) {out.close();}
    			} catch (Exception e) {}
    		}
    	}
    
    	/**
    	 * 递归压缩方法
    	 * @param sourceFile 源文件
    	 * @param zos zip输出流
    	 * @param name 压缩后的名称
    	 */
    	private static void compress(File sourceFile, ZipOutputStream zos, String name)
    			throws Exception {
    		byte[] buf = new byte[BUFFER_SIZE];
    		if (sourceFile.isFile()) {
    			zos.putNextEntry(new ZipEntry(name));
    			int len;
    			FileInputStream in = new FileInputStream(sourceFile);
    			while ((len = in.read(buf)) != -1) {
    				zos.write(buf, 0, len);
    			}
    			zos.closeEntry();
    			in.close();
    		} else {
    			File[] listFiles = sourceFile.listFiles();
    			if (listFiles == null || listFiles.length == 0) {
    				if (KeepDirStructure) {
    					zos.putNextEntry(new ZipEntry(name + "/"));
    					zos.closeEntry();
    				}
    			} else {
    				for (File file : listFiles) {
    					if (KeepDirStructure) {
    						compress(file, zos, name + "/" + file.getName());
    					} else {
    						compress(file, zos, file.getName());
    					}
    				}
    			}
    		}
    	}
    	
    	// 删除文件或文件夹以及文件夹下所有文件
    	public static void delDir(String dirPath) throws IOException {
    		log.info("删除文件开始:{}.",dirPath);
    		long start = System.currentTimeMillis();
    		try{
    			File dirFile = new File(dirPath);
    			if (!dirFile.exists()) {
    				return;
    			}
    			if (dirFile.isFile()) {
    				dirFile.delete();
    				return;
    			}
    			File[] files = dirFile.listFiles();
    			if(files==null){
    				return;
    			}
    			for (int i = 0; i < files.length; i++) {
    				delDir(files[i].toString());
    			}
    			dirFile.delete();
    			log.info("删除文件:{}. 耗时:{}ms. ",dirPath,System.currentTimeMillis()-start);
    		}catch(Exception e){
    			log.info("删除文件:{}. 异常:{}. 耗时:{}ms. ",dirPath,e,System.currentTimeMillis()-start);
    			throw new IOException("删除文件异常.");
    		}
    	}
    }
    

      将zip进行解压

    /**
     * 解压文件到指定目录
     * @explain
     * @param zipPath 压缩包的绝对完整路径
     * @param outDir 解压到哪个地方
     * @throws IOException
     */
    @SuppressWarnings({ "rawtypes", "resource" })
    public static void unZipFiles(String zipPath, String outDir) throws IOException {
        log.info("文件:{}. 解压路径:{}. 解压开始.",zipPath,outDir);
        long start = System.currentTimeMillis();
        try{
            File zipFile = new File(zipPath);
            System.err.println(zipFile.getName());
            if(!zipFile.exists()){
                throw new IOException("需解压文件不存在.");
            }
            File pathFile = new File(outDir);
            if (!pathFile.exists()) {
                pathFile.mkdirs();
            }
            ZipFile zip = new ZipFile(zipFile, Charset.forName("GBK"));
            for (Enumeration entries = zip.entries(); entries.hasMoreElements();) {
                ZipEntry entry = (ZipEntry) entries.nextElement();
                String zipEntryName = entry.getName();
                System.err.println(zipEntryName);
                InputStream in = zip.getInputStream(entry);
                String outPath = (outDir + File.separator + zipEntryName).replaceAll("\*", "/");
                System.err.println(outPath);
                // 判断路径是否存在,不存在则创建文件路径
                File file = new File(outPath.substring(0, outPath.lastIndexOf('/')));
                if (!file.exists()) {
                    file.mkdirs();
                }
                // 判断文件全路径是否为文件夹,如果是上面已经上传,不需要解压
                if (new File(outPath).isDirectory()) {
                    continue;
                }
                // 输出文件路径信息
                OutputStream out = new FileOutputStream(outPath);
                byte[] buf1 = new byte[1024];
                int len;
                while ((len = in.read(buf1)) > 0) {
                    out.write(buf1, 0, len);
                }
                in.close();
                out.close();
            }
            log.info("文件:{}. 解压路径:{}. 解压完成. 耗时:{}ms. ",zipPath,outDir,System.currentTimeMillis()-start);
        }catch(Exception e){
            log.info("文件:{}. 解压路径:{}. 解压异常:{}. 耗时:{}ms. ",zipPath,outDir,e,System.currentTimeMillis()-start);
            throw new IOException(e);
        }
    }
    

      测试

    public static void main(String[] args) {
        try {
            // 压缩
            toZip("D:\apache-maven-3.5.3\maven中央仓库-jar下载", "D:\apache-maven-3.5.3\maven中央仓库-jar下载.zip",true);
            // 解压
            //unZipFiles("D:\\apache-maven-3.5.3\\maven中央仓库-jar下载.zip","D:\apache-maven-3.5.3");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    

      方式二:压缩成zip可设密码

      所需jar包:zip4j_1.3.1.jar

    package base.web.tools;
    
    import java.io.FileNotFoundException;
    
    import org.apache.commons.lang.StringUtils;
    import net.lingala.zip4j.core.ZipFile;
    import net.lingala.zip4j.exception.ZipException;
    import net.lingala.zip4j.model.ZipParameters;
    import net.lingala.zip4j.util.Zip4jConstants;
    
    
    /**
     * <ul>
     * <li>支持多层次目录ZIP压缩的工具</li>
     * <li>用法 :</li>
     * <li>1.普通压缩, Zipper.packageFolder(folder, target);</li>
     * <li>2.加密码的压缩 , Zipper.packageFolderWithPassword(folder, target, password);</li>
     * <li>参数说明:</li>
     * <ol>
     * <li>folder 待压缩的目录</li>
     * <li>target 目标文件路径</li>
     * </ol>
     * </ul>
     */
    public class Zipper {
    
    	/**
    	 * 压缩文件夹
    	 * @expalin 如果已经存在相同的压缩包,则会覆盖之前的压缩包
    	 * @param folder 要打包的文件夹的磁盘路径
    	 * 比如,D:\aa\bb
    	 * @param target 存放打包后的压缩包的磁盘路径
    	 * 构成:路径+压缩包名称.后缀名
    	 * 比如,D:\aa\bb.zip
    	 * @throws ZipException
    	 */
    	public static void packageFolder(String folder, String target) throws ZipException {
    		packageFolderWithPassword(folder, target, null);
    	}
    	
    	public static void packageFolderWithPassword(String folder, String target, String password) throws ZipException{
    		ZipFile zip = new ZipFile(target);
    		ZipParameters parameters = new ZipParameters();
    		parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE); 
    		parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL); 
    		// 加密
    		if(StringUtils.isNotBlank(password)){
    			parameters.setEncryptFiles(true);
    			parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);
    			parameters.setPassword(password);
    		}
    		
    		zip.addFolder(folder, parameters);
    	}
    
    	public static void main(String[] args) throws FileNotFoundException {
    		try {
    			packageFolder("D:\aa\bb", "D:\aa\bb.zip");
    		} catch (ZipException e) {
    			e.printStackTrace();
    		}
    	}
    }
    

      

    写在最后

      哪位大佬如若发现文章存在纰漏之处或需要补充更多内容,欢迎留言!!!

     相关推荐:

  • 相关阅读:
    The user specified as a definer ('root'@'%') does not exist
    Linux安装卸载查看vsftpd
    【数据分析】算法+Echarts小练
    【leecode】小练习(简单8题)
    路飞学城Python-Day171
    【路飞学城Day170】算法小结
    【路飞学城第七模块考核】
    【leecode】独特的电子邮件地址
    【leecode】宝石与石头
    路飞学城Python-Day153
  • 原文地址:https://www.cnblogs.com/Marydon20170307/p/12597684.html
Copyright © 2011-2022 走看看