zip4j压缩

时间:2022-09-27 00:00:21

使用的jar包:zip4j_1.3.2.jar
基本功能:
针对ZIP压缩文件创建、添加、分卷、更新和移除文件
(读写有密码保护的Zip文件)
(支持AES 128/256算法加密)
(支持标准Zip算法加密)
(支持zip64格式)
(支持Store(仅打包,默认不压缩,不过可以手动设置大小)和Deflate压缩方法
(针对分块zip文件创建和抽出文件)
(支持编码)
(进度监控)
压缩方式(3种):
static final int COMP_STORE = 0;(仅打包,不压缩) (对应好压的存储)
static final int COMP_DEFLATE = 8;(默认) (对应好压的标准)
static final int COMP_AES_ENC = 99;

压缩级别有5种:(默认0不压缩)级别跟好压软件是对应的;
static final int DEFLATE_LEVEL_FASTEST = 1;
static final int DEFLATE_LEVEL_FAST = 3;
static final int DEFLATE_LEVEL_NORMAL = 5;
static final int DEFLATE_LEVEL_MAXIMUM = 7;
static final int DEFLATE_LEVEL_ULTRA = 9;
加密方式:
static final int ENC_NO_ENCRYPTION = -1;(默认,没有加密方法,如果采用此字段,会报错”没有提供加密算法”)
static final int ENC_METHOD_STANDARD = 0;
static final int ENC_METHOD_AES = 99;
AES Key Strength:
(默认-1,也就是ENC_NO_ENCRYPTION)
static final int AES_STRENGTH_128 = 0x01;
static final int AES_STRENGTH_192 = 0x02;
static final int AES_STRENGTH_256 = 0x03;

从构造方法可以默认情况:
compressionMethod = Zip4jConstants.COMP_DEFLATE;
encryptFiles = false;//不设密码
readHiddenFiles = true;//可见
encryptionMethod = Zip4jConstants.ENC_NO_ENCRYPTION;//加密方式不加密
aesKeyStrength = -1;//
includeRootFolder = true;//
timeZone = TimeZone.getDefault();//

**
* 情景教学压缩操作类
*/
public class CompressHandler extends Thread { private Logger logger = Logger.getLogger(CompressHandler.class); /**
* 存储目录名和对应目录下的文件地址
*/
private Map<String, List<ResourceInfo>> resourceMap; /**
* 压缩类中的配置文件
*/
private String configJson; /**
* 配置文件map key为压缩包中的文件名,value为文件内容
*/
Map<String, String> configJsonMap; /**
* 回调接口
*/
private ZipOperate zipOperate; /**
* 加密标志
*/
private boolean encrypt = false; /**
* 线程名称
*/
private String threadName = Thread.currentThread().getName(); /**
* 取消标志
*/
private boolean cancelFlag; public CompressHandler() {
} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String> configJsonMap, ZipOperate zipOperate) {
this(resourceMap, configJsonMap, zipOperate, false);
} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, Map<String, String> configJsonMap, ZipOperate zipOperate, boolean encrypt) {
this.resourceMap = resourceMap;
this.configJsonMap = configJsonMap;
this.zipOperate = zipOperate;
this.encrypt = encrypt;
} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, String configJson, ZipOperate zipOperate) {
this(resourceMap, configJson, zipOperate, false);
} public CompressHandler(Map<String, List<ResourceInfo>> resourceMap, String configJson, ZipOperate zipOperate, boolean encrypt) {
this.resourceMap = resourceMap;
this.configJson = configJson;
this.zipOperate = zipOperate;
this.encrypt = encrypt;
} @Override
public void run() {
if (zipOperate != null) {
zipOperate.beforeCompress();
}
String fileName = UUID.randomUUID().toString().replace("-", "").concat(".zip");
String tempDir = SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TMMP_FILE_PATH);
File tempDirFile = new File(tempDir);
if (!tempDirFile.exists()) {
tempDirFile.mkdir();
}
String filePath = tempDir.concat("/").concat(fileName);
//存储生成本地压缩包的文件
List<File> encryptFileList = new ArrayList<>();
try {
ZipFile zipFile = new ZipFile(filePath);
logger.info("线程" + threadName + " 开始压缩,压缩的文件名为:" + fileName);
long startTime = System.currentTimeMillis();
logger.info("线程" + threadName + " 开始时间为:" + startTime);
ZipParameters parameters = new ZipParameters();
//设置压缩方式和压缩级别
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
//当开启压缩包密码加密时
boolean dirEncrypt = false;
if (encrypt || Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.ENABLE_ENCRYPT_ZIP))) {
logger.info("线程" + threadName + " 该压缩包需要加密");
addEncryptParameters(parameters);
dirEncrypt = true;
}
for (String dir : resourceMap.keySet()) {
logger.info("线程" + threadName + " 添加目录:" + dir);
List<ResourceInfo> resourceInfoList = resourceMap.get(dir);
for (ResourceInfo resourceInfo : resourceInfoList) {
String resourceFileName = resourceInfo.getFileName();
logger.info("线程" + threadName + " 添加文件:" + resourceFileName);
/**
* 20180921判断目录名是否为空字符串 true不创建目录 by lizhang10
*/
if(StringUtils.isNotEmpty(dir)){
parameters.setFileNameInZip(dir + "/" + resourceFileName);
}else{
parameters.setFileNameInZip(resourceFileName);
}
parameters.setSourceExternalStream(true);
InputStream inputStream = resourceInfo.getInputStream();
if (inputStream == null) {
//获取文件流
String fileUrl = resourceInfo.getFileUrl();
long startTime1 = System.currentTimeMillis();
logger.info("线程" + threadName + " 开始获取文件流,地址:" + fileUrl + " 开始时间:" + startTime1);
inputStream = getInputStream(fileUrl);
long endTime1 = System.currentTimeMillis();
logger.info("线程" + threadName + " 结束获取文件流,地址:" + fileUrl + " 结束时间:" + endTime1 + " 耗时毫秒: " + (endTime1 - startTime1));
}
//当压缩包没有加密时,则从文件属性中取是否进行加密
if(!dirEncrypt && resourceInfo.isEncrypt()){
//如果是zip的话,则对文件进行解压,然后再加密
if(resourceFileName.endsWith(".zip")){
long saveStartTime = System.currentTimeMillis();
//网络文件路径
String sourceFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip"));
logger.info("线程" + threadName + " 该文件["+resourceFileName+"]是zip且需要加密,开始存到本地,路径为:"+sourceFileName+"开始时间:" + saveStartTime);
//加密文件路径
String encryptFileName = tempDir.concat("/").concat(UUID.randomUUID().toString().concat(".zip"));
File file = new File(sourceFileName);
FileOutputStream outputStream = new FileOutputStream(file);
byte[] buffer = new byte[8*1024];
int len = 0;
while ((len = inputStream.read(buffer)) != -1){
outputStream.write(buffer,0,len);
}
outputStream.close();
inputStream.close();
long saveEndTime = System.currentTimeMillis();
logger.info("线程" + threadName + " 该文件是zip,存到本地完成,结束时间:" + saveEndTime + " 耗时:"+(saveEndTime - saveStartTime));
long extractStartTime = System.currentTimeMillis();
logger.info("线程" + threadName + " ,开始进行解压加密,开始时间为:" + extractStartTime);
ZipFile sourceZipFile = new ZipFile(file);
String extractDir = tempDir.concat("/").concat(UUID.randomUUID().toString());
sourceZipFile.extractAll(extractDir);
long extractEndTime = System.currentTimeMillis();
ZipFile encryptZipFile = new ZipFile(encryptFileName);
ZipParameters parameters2 = new ZipParameters();
//设置压缩方式和压缩级别
parameters2.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);
parameters2.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);
addEncryptParameters(parameters2);
//添加获取文件的文件和目录
File[] fileArray = new File(extractDir).listFiles();
for (File file1 : fileArray) {
if(file1.isDirectory()){
encryptZipFile.addFolder(file1,parameters2);
} else {
encryptZipFile.addFile(file1,parameters2);
}
}
if(!StringUtils.isEmpty(resourceInfo.getConfigJson())){
parameters2.setFileNameInZip("config.json");
parameters2.setSourceExternalStream(true);
encryptZipFile.addStream(new ByteArrayInputStream(resourceInfo.getConfigJson().getBytes("utf8")),parameters2);
}
logger.info("线程" + threadName + " ,完成解压加密,结束时间为:" + extractEndTime + " 耗时: " + (extractEndTime-extractStartTime));
//删除文件
sourceZipFile.getFile().delete();
//删除目录下的文件
deleteFolder(new File(extractDir));
File encryptFile = encryptZipFile.getFile();
inputStream = new FileInputStream(encryptFile);
encryptFileList.add(encryptFile);
}
}
//获取需要打包的文件流
zipFile.addStream(inputStream, parameters);
inputStream.close();
}
}
parameters.setSourceExternalStream(true);
//如果configJsonMap不为空,且length不为0,则遍历加入到压缩包中
if (configJsonMap != null && configJsonMap.size() > 0) {
for (String resourceName : configJsonMap.keySet()) {
logger.info("线程" + threadName + " 添加配置文件" + resourceName);
parameters.setFileNameInZip(resourceName);
String value = configJsonMap.get(resourceName);
zipFile.addStream(new ByteArrayInputStream(value.getBytes("utf8")), parameters);
}
}
if (!StringUtils.isEmpty(configJson)) {
logger.info("线程" + threadName + " 添加文件config.json");
parameters.setFileNameInZip("config.json");
zipFile.addStream(new ByteArrayInputStream(configJson.getBytes("utf8")), parameters);
}
logger.info("线程" + threadName + " 压缩文件" + fileName + "完成");
long endTime = System.currentTimeMillis();
logger.info("线程" + threadName + " 结束时间为:" + endTime + " 耗时毫秒:" + (endTime - startTime));
long startTime2 = System.currentTimeMillis();
logger.info("线程" + threadName + " 开始将压缩包上传到文件服务.......开始时间:" + startTime2);
FileInfo fileInfo = new CystrageUtil().uploadToRemoteServer(fileName, filePath, null);
long endTime2 = System.currentTimeMillis();
logger.info("线程" + threadName + " 上传完成.......结束时间:" + endTime2 + "耗时毫秒: " + (endTime2 - startTime2));
if (cancelFlag){
throw new InterruptedException("线程" + threadName + " 取消压缩");
}
//如果传入了后续操作接口,则将文件服务返回的类传入
if (zipOperate != null) {
zipOperate.afterCompress(fileInfo, zipFile);
zipFile.getFile().delete();
}
} catch (Exception e) {
logger.error("线程" + threadName + " 文件压缩出错...........文件内容:" + configJson, e);
if (zipOperate != null) {
zipOperate.errorCompress();
}
//删除对应压缩包
new File(filePath).delete();
} finally {
try {
//关流
inputStream.close();
} catch (IOException e) {
inputStream = null;
}
//删除本地生成的压缩文件
//存储生成本地压缩包的文件
for (File file : encryptFileList) {
file.delete();
}
}
} /**
* 删除文件夹下的所有文件
* @param sourceDir
*/
private void deleteFolder(File sourceDir) {
if(sourceDir.isDirectory()){
File[] files = sourceDir.listFiles();
for (File file : files) {
deleteFolder(file);
}
} else {
sourceDir.delete();
}
sourceDir.delete();
} private void addEncryptParameters(ZipParameters parameters) {
String password = SuperdiamondConfig.getConfig(SuperdiamondConfig.ZIP_COMPRESS_PASSWORD);
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_AES);
parameters.setAesKeyStrength(Zip4jConstants.AES_STRENGTH_256);
parameters.setPassword(password.toCharArray());
} /**
* 获取输入流
*
* @param fileUrl
* @return
*/
InputStream inputStream; private InputStream getInputStream(String fileUrl) throws Exception {
if(cancelFlag){
throw new InterruptedException("线程" + threadName + " 取消压缩");
}
int retry = 1;
while (retry <= 3) {
try {
int index = fileUrl.lastIndexOf("/");
String prefix = fileUrl.substring(0, index + 1);
String fileName = fileUrl.substring(index + 1);
URL url = new URL(prefix + URLEncoder.encode(fileName, "utf8"));
URLConnection connection = url.openConnection();
connection.setDoInput(true);
inputStream = connection.getInputStream();
return inputStream;
} catch (Exception e) {
if (retry == 1) {
logger.error("线程" + threadName + " 获取文件出错,文件地址:" + fileUrl, e);
}
logger.error("开始重试第" + retry + "次");
//由于测试环境服务器承载能力比较差,当获取失败后,睡眠一段时间再重试
if(Boolean.parseBoolean(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_TEST_ENVIRONMENT))){
Thread.currentThread().sleep(Long.parseLong(SuperdiamondConfig.getConfig(SuperdiamondConfig.SYSTEM_SLEEP_TIME)));
}
if (retry == 3) {
throw new Exception(e);
}
retry++;
}
}
return null;
} public void setCancelFlag(Boolean cancelFlag){
this.cancelFlag = cancelFlag;
} @Override
public void interrupt() {
if (inputStream != null) {
try {
inputStream.close();
} catch (IOException e) {
inputStream = null;
logger.info("线程" + threadName + " 关闭io流失败");
}
}
super.interrupt();
} public static class ResourceInfo {
/**
* 文件名称
*/
private String fileName; /**
* 文件地址
*/
private String fileUrl; /**
* 输入流
*/
private InputStream inputStream; /**
* 是否要为当前文件添加config,json
*/
private String configJson; /**
* 改文件是否加密
*/
private boolean encrypt; public InputStream getInputStream() {
return inputStream;
} public void setInputStream(InputStream inputStream) {
this.inputStream = inputStream;
} public String getFileName() {
return fileName;
} public void setFileName(String fileName) {
this.fileName = fileName;
} public String getFileUrl() {
return fileUrl;
} public void setFileUrl(String fileUrl) {
this.fileUrl = fileUrl;
} public boolean isEncrypt() {
return encrypt;
} public void setEncrypt(boolean encrypt) {
this.encrypt = encrypt;
} public String getConfigJson() {
return configJson;
} public void setConfigJson(String configJson) {
this.configJson = configJson;
}
}
}

zip4j压缩的更多相关文章

  1. 【Java】:压缩成多个压缩卷

    Java自带的库不支持压缩成多个压缩卷,找到了一个开源库 zip4j ,发现更好用 so easy package com.jws.common.mail; import java.io.File; ...

  2. java zip4j 内存文件和磁盘文件 压缩和加密

    经常服务器需要对文件进行压缩,网络上流传较多的是从磁盘文件中来压缩成zip文件.但是常常服务器的文件存放在内存中,以byte[]形式存储在内存中.这个时候就不能使用网络上流传的常用方法了,这里就需要对 ...

  3. zip4j实现文件压缩与解压缩 &amp&semi; common-compress压缩与解压缩

    有时候需要批量下载文件,所以需要在后台将多个文件压缩之后进行下载. zip4j可以进行目录压缩与文件压缩,同时可以加密压缩. common-compress只压缩文件,没有找到压缩目录的API. 1. ...

  4. zip4j加密压缩、解压缩文件、文件夹

    原文:http://blog.csdn.net/k21325/article/details/54376188 1.首先,引用到zip4j的第三方类库,感谢作者的无私奉献,官网打不开,这里就不贴了,下 ...

  5. zip4j 2&period;0压缩 加密压缩

    https://github.com/srikanth-lingala/zip4j ZipParameters zipParameters = new ZipParameters(); zipPara ...

  6. Zip文件压缩(加密&vert;&vert;非加密&vert;&vert;压缩指定目录&vert;&vert;压缩目录下的单个文件&vert;&vert;根据路径压缩&vert;&vert;根据流压缩)

    1.写入Excel,并加密压缩.不保存文件 String dcxh = String.format("%03d", keyValue); String folderFileName ...

  7. JAVA利用Zip4j解压缩【转】

    官方地址:http://www.lingala.net/zip4j/(需要FQ) jar包:http://pan.baidu.com/s/145hwI 演示包:http://pan.baidu.com ...

  8. Zip4J最简单用法

    package com.chentao.MicroMessage.bussiness; import java.io.File; import java.util.ArrayList; import ...

  9. springboot添加邮件发送及压缩功能

    springboot添加邮件发送及文件压缩功能 转载请注明出处:https://www.cnblogs.com/funnyzpc/p/9190233.html 先来一段诗 ``` 就这样吧 忍受折磨 ...

随机推荐

  1. 用c&num;开发微信(5)自定义菜单设置工具 (在线创建)

    读目录 1 使用 2 原理 3. 错误 上次写了<用c#开发微信 (4) 基于Senparc.Weixin框架的接收事件推送处理 (源码下载)>,有园友问到如何创建菜单的问题,今天就介绍下 ...

  2. linux

    托瓦兹跟BBS上面一堆工秳师一样, 他发现Minix虽然真癿很棒,但是谭宁邦教授就是丌愿意迚行功能癿加强,导致一堆工秳师在操作系统功能上面癿欲求丌满! 这个时候年轻癿托瓦兹就想:『既然如此,那我何丌自 ...

  3. Android开发--Android Studio配置

    1.常见问题 emulator: You might want to adjust your AVD RAM size and/or HAXM configuration to run in fast ...

  4. DotNetZip封装类

      DotnetZip是一个开源类库,支持.NET的任何语言,可很方便的创建,读取,和更新zip文件.而且还可以使用在.NETCompact Framework中. 下载地址在这里: http://d ...

  5. 1047 - Neighbor House(简单线性DP)

    题目大意: 给你n个房子,要求把房子染成R,G,B三种的一种颜色, 要求相邻的颜色不能一样. dp[第i个房子][第j种颜色]  转移一下就行了.       #include<cstdio&g ...

  6. 理解Javascript 的闭包(closure)

    要理解闭包的概念先从变量的作用域说去 一.变量的作用域 要理解闭包,首先必须理解Javascript特殊的变量作用域. 变量的作用域无非就是两种:全局变量和局部变量. Javascript语言的特殊之 ...

  7. 【js】name 与 array 的纠葛 - 坑

    一. 现象 var name = new Array(); typeof(name)      // 为string 类型 var name = new Array('a' , 'b' , 'c'); ...

  8. CentOS7安装MySQL的方法之RPM包方式

        CentOS7安装MySQL的方法之RPM包方式        

  9. 3&period;python元类编程

     1.1.propety动态属性 在面向对象编程中,我们一般把名词性的东西映射成属性,动词性的东西映射成方法.在python中他们对应的分别是属性self.xxx和类方法.但有时我们需要的属性需要根据 ...

  10. Linux&lpar;CentOS7&rpar;yum安装卸载命令,离线下载安装包

    一.Linux版本 二.yum安装 比如安装vim编辑器,y是自动应答,即默认一路确认,不用中途确认 yum install -y vim 三.yum卸载 比如卸载掉刚刚安装的vim yum eras ...