压缩加密文件工具类

此工具类可以压缩和解压文件,支持设置解压密码。

说明:
1 压缩文件时候判定被压缩文件是否存在, 不存在会报错。
2 示例是压缩txt,也可以doc,pdf,xlsx等其他文件。
3 压缩和解压不同文件类型可通用,但解压不同文件类型读取内容的写法略有不同。
4 依赖包zip4j_1.3.1.jar, ant.jar

zipUtil.java

package zipTest;

import java.io.BufferedInputStream;
/**
 * 文件压缩加密码解密工具类
 * 
 * @author yulisao
 * @createDate 2020年8月21日
 */
public class zipUtil {
	private static final int  BUFFER_SIZE = 2 * 1024;
	/**
	 * 加密单个压缩文件
	 * 
	 * @param zipFile 完整路径输出压缩包
	 * @param addFile 被压缩文件
	 * @param password 解压密码
	 */
    public static void encryZipFile(File zipFile,File addFile,String password){
    	
    	if (!addFile.exists()) {
			return;
		}
 
        try {
            //创建压缩文件
            ZipFile respFile = new ZipFile(zipFile);
 
            //设置压缩文件参数
            ZipParameters parameters = new ZipParameters();
            
            //设置压缩方法
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
 
            //设置压缩级别
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
 
            //设置压缩文件加密
            parameters.setEncryptFiles(true);
 
            //设置加密方法
            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
 
            //设置aes加密强度
            parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
 
            //设置密码
            parameters.setPassword(password);
            
            //添加文件到压缩文件
            respFile.addFile(addFile,parameters);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        
        System.out.println("压缩成功,文件存储路径 " + zipFile.getAbsolutePath());
        
    }
    
    /**
	 * 加密单多压缩文件
	 * 
	 * @param zipFile 完整路径输出压缩包
	 * @param addFile 被压缩文件
	 * @param password 解压密码
	 */
    public static void encryZipFiles(File zipFile,ArrayList<File> filesList,String password){
    	
        try {
            //创建压缩文件
            ZipFile respFile = new ZipFile(zipFile);
 
            //设置压缩文件参数
            ZipParameters parameters = new ZipParameters();
            
            //设置压缩方法
            parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
 
            //设置压缩级别
            parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
 
            //设置压缩文件加密
            parameters.setEncryptFiles(true);
 
            //设置加密方法
            parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
 
            //设置aes加密强度
            parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
 
            //设置密码
            parameters.setPassword(password);
            
            //添加文件到压缩文件
            respFile.addFiles(filesList,parameters);
        } catch (ZipException e) {
            e.printStackTrace();
        }
        
        System.out.println("压缩成功,文件存储路径 " + zipFile.getAbsolutePath());
        
    }
    
    /**
     * 压缩指定的多个文件(不设置密码 )
     * 
     * @param fileList 文件列表
     * @param outPath 压缩包输出路径
     */
    public static void zipFile(List<File> fileList , String outPath) {
		ZipOutputStream zos = null ;	
        try {
            zos = new ZipOutputStream(new FileOutputStream(new File(outPath)));
            for (File file : fileList) {
                byte[] buf = new byte[BUFFER_SIZE];
                zos.putNextEntry(new ZipEntry(file.getName()));
                int len;
                FileInputStream in = new FileInputStream(file);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }

        } catch (Exception e) {
            throw new RuntimeException("zip file run error!",e);
        } finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

        }
        
        System.out.println("压缩成功,文件存储路径 " + outPath);
	
	}
    
    /**
	 * 压缩文件/文件夹(不设置密码 )
	 *
	 * @param targetFilePath 源文件路径
	 * @param outZipPath 压缩后文件存储路径
	 * @param isDeleteOld 压缩后是否删除源文件
	 */
	public static void compressToZip(String targetFilePath, String outZipPath, boolean isDeleteOld) {
		File targetFile = new File(targetFilePath); // 被压缩路径
		File zipFile = new File(outZipPath); // 压缩包输出路径
		
		try (ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(zipFile))) { //java7 支持自动关闭流
			writeToZip(targetFile, "", zos);
			if (isDeleteOld) {
				deleteDir(targetFile); //压缩完后删原件
			}
			System.out.println("压缩成功,文件存储路径 " + outZipPath);
		} catch (Exception e) {
			e.printStackTrace();
			throw new RuntimeException(e.getMessage(), e.getCause());
		}
	}

	/**
	 * 回归处理
	 *
	 * @param targetFile 源文件目录
	 * @param currentDir 压缩文件目录
	 * @param zos 文件流
	 */
	private static void writeToZip(File targetFile, String currentDir, ZipOutputStream zos) {
		if (targetFile.isDirectory()) { // 若当前处理的是目录, 循环回归
			currentDir += targetFile.getName() + File.separator;
			File[] files = targetFile.listFiles();
			for (File file : files) {
				writeToZip(file, currentDir, zos);
			}
		} else { // 若当前处理的是文件, 压缩
			try (BufferedInputStream bis = new BufferedInputStream(new FileInputStream(targetFile))) { 
				ZipEntry zipEntry = new ZipEntry(currentDir + targetFile.getName());
				zos.putNextEntry(zipEntry);
				int len;
				byte[] buffer = new byte[1024 * 10];
				while ((len = bis.read(buffer, 0, buffer.length)) != -1) {
					zos.write(buffer, 0, len);
					zos.flush();
				}
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException(e.getMessage(), e.getCause());
			}
		}
	}

	/**
	 * 删除文件夹
	 *
	 * @param targetDir
	 * @return
	 */
	private static boolean deleteDir(File targetDir) {
		// 是文件就循环回归,是文件就直接delete,
		if (targetDir.isDirectory()) {
			String[] children = targetDir.list();
			for (int i = 0; i < children.length; i++) {
				boolean success = deleteDir(new File(targetDir, children[i]));
				if (!success) {
					return false;
				}
			}
		}

		return targetDir.delete(); // 删除文件
	}
	
	/**
	 * 压缩文件/文件夹(不设置密码 ,减少中文乱码)
	 * 
	 * @param targetFilePath 被压缩目标路径
	 * @param zipFilePath 压缩包输出路径
	 */
	public static void compressToZip(String targetFilePath, String zipFilePath) {  
		File zipFile = new File(zipFilePath);
        File targetFile = new File(targetFilePath);  
        if (!targetFile.exists()){
            throw new RuntimeException(targetFilePath + "不存在!");  
        } 
          
        Project prj = new Project();  
        Zip zip = new Zip();  
        zip.setProject(prj);  
        zip.setDestFile(zipFile);  
        FileSet fileSet = new FileSet();  // FileSet的方法很多,比如setExcludes:过滤不压缩,具体可以参阅文档
        fileSet.setProject(prj);  
        fileSet.setDir(targetFile);  
        zip.addFileset(fileSet);  
        zip.execute();  
        
        System.out.println("压缩成功,文件存储路径 " + zipFilePath);
    } 
    
    /**
	 * 解密
	 * 
	 * @param zipFilePath 压缩文件
	 * @param outPath 解压路径
	 * @param password 解压密码
	 * @throws ZipException
	 * @throws IOException
	 */
    public static void decryptZipFile(String zipFilePath, String outPath, String password) throws ZipException, IOException {
    	ZipFile zipFile = new ZipFile(zipFilePath);
    	
        zipFile.setFileNameCharset("GBK");//设置编码格式
        if (!zipFile.isValidZipFile()) {
            throw new ZipException("文件不合法或不存在");
        }
        
        if (zipFile.isEncrypted()) { //检查是否需要密码
            zipFile.setPassword(password);
        }
        
        if (StringUtils.isBlank(outPath)) { // 默认解压到当前路径
			outPath = zipFilePath.substring(0,zipFilePath.lastIndexOf(File.separator));
		} else { // 检查目录是否存在
			File outDir = new File(outPath);
	        if (!outDir.exists()) {
	        	outDir.mkdir();
			}
		}
        outPath = outPath.endsWith(File.separator) ? outPath:outPath+File.separator;
                
        List<FileHeader> fileHeaderList = zipFile.getFileHeaders(); // 获取解压文件
        for (int i = 0; i < fileHeaderList.size(); i++) {
            FileHeader fileHeader = fileHeaderList.get(i);
           
            // 文件输出
            InputStream input = zipFile.getInputStream(fileHeader);// 获取流
            int index;
    		byte[] bytes = new byte[1024];
    		FileOutputStream downloadFile = new FileOutputStream(outPath + fileHeader.getFileName());// 创建同原文件名文件写入
    		while ((index = input.read(bytes)) != -1) {
    			downloadFile.write(bytes, 0, index);
    			downloadFile.flush();
    		}
    		downloadFile.close();
    		input.close();

            
			// 读取文件内容
			BufferedReader reader = new BufferedReader(new InputStreamReader(zipFile.getInputStream(fileHeader)));
			String line;
			try {
				while ((line = reader.readLine()) != null) {
					System.out.println(line); // and do something
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
        }
        System.out.println("解压成功至 " + outPath);
    }

}


测试类

package zipTest;


import java.io.File;


/**
 * 压缩包工具类测试主类
 * 
 * @author yulisao
 * @createDate 2020年8月26日
 */
public class zipUtilTest {
	

	public static void main(String[] args) {
		String  pwd  = "123456";
		String filePath1 = "C:\\Users\\Administrator\\Desktop\\ziptest\\11.txt"; // 被压缩的文件
		String filePath2 = "C:\\Users\\Administrator\\Desktop\\ziptest\\22.txt"; // 被压缩的文件
		String filePath3 = "C:\\Users\\Administrator\\Desktop\\ziptest"; // 被压缩的文件
		String  zipPath1  = "C:\\Users\\Administrator\\Desktop\\outtest\\single.zip" ; // 压缩包输出
		String  zipPath2  = "C:\\Users\\Administrator\\Desktop\\outtest\\double.zip" ; // 压缩包输出
		String  zipPath3  = "C:\\Users\\Administrator\\Desktop\\outtest\\nopwd.zip" ; // 压缩包输出
		String  zipPath4  = "C:\\Users\\Administrator\\Desktop\\outtest\\all.zip" ; // 压缩包输出
		String  zipPath5  = "C:\\Users\\Administrator\\Desktop\\outtest\\allant.zip" ; // 压缩包输出
		File file = new File(filePath1);
		File zipFile1 = new File(zipPath1);
		File zipFile2 = new File(zipPath2);
		
		
		// 单个文件压缩
		zipUtil.encryZipFile(zipFile1,file,pwd);
		
		// 多个文件压缩
	    ArrayList<File> filesList = new ArrayList<File>();
	    File file1 = new File(filePath1);
	    if (!file1.exists()) {
			return;
		}
	    filesList.add(file1);
	    File file2 = new File(filePath2);
	    if (!file2.exists()) {
			return;
		}
	    filesList.add(file2);
	    // 有多少文件继续加....
	    zipUtil.encryZipFiles(zipFile2,filesList,pwd);

	    // 无密压缩
	    zipUtil.zipFile(filesList, zipPath3);
	    
	    // 无密压缩文件夹,依赖 ant.jar
	    zipUtil.compressToZip(filePath3, zipPath5);
	    
	    // 无密压缩文件夹,递归
	    zipUtil.compressToZip(filePath3, zipPath4, false);
	    
	    System.err.println("解密开始");
	    
	    // 解密
		String  zipPath  = "C:\\Users\\Administrator\\Desktop\\outtest\\double.zip" ; // 压缩包输出
		String  outPath = "C:\\Users\\Administrator\\Desktop\\outtest\\decrypt\\";
		
		
		try {
			zipUtil.decryptZipFile(zipPath,outPath, pwd);
		} catch (IOException e) {
			e.printStackTrace();
		} catch (ZipException e) {
			e.printStackTrace();
		}
		
	}


}


运行结果:
在这里插入图片描述

压缩文件方法 该方法需要引用zip4j的jar文件 单个文件、多个文件压缩 /** * 使用给定密码压缩指定文件文件夹到指定位置. * * dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者"". * 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀; * 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名. * @param src 要压缩文件文件夹路径 * @param dest 压缩文件存放路径 * @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效. * 如果为false,将直接压缩目录下文件压缩文件. * @param passwd 压缩使用的密码 * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. */ 方法详细见文件! 可选择文件list压缩 /** * 使用给定密码压缩指定文件list * dest可传最终压缩文件存放的绝对路径,也可以传存放目录,也可以传null或者"". * 如果传null或者""则将压缩文件存放在当前目录,即跟源文件同目录,压缩文件名取源文件名,以.zip为后缀; * 如果以路径分隔符(File.separator)结尾,则视为目录,压缩文件名取源文件名,以.zip为后缀,否则视为文件名. * @param src 要压缩文件集合 * @param dest 压缩文件存放路径 * @param isCreateDir 是否在压缩文件里创建目录,仅在压缩文件为目录时有效. * 如果为false,将直接压缩目录下文件压缩文件. * @param passwd 压缩使用的密码 * @return 最终的压缩文件存放的绝对路径,如果为null则说明压缩失败. */ 方法详细见文件! 解压 /** * 使用给定密码解压指定的ZIP压缩文件到指定目录 * * 如果指定目录不存在,可以自动创建,不合法的路径将导致异常被抛出 * @param zipFile 指定的ZIP压缩文件 * @param dest 解压目录 * @param passwd ZIP文件的密码 * @return 解压后文件数组 * @throws ZipException 压缩文件有损坏或者解压缩失败抛出 */ 方法详细见文件! 一个简单的demo 欢迎大家指点,一起提升
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值