Java使⽤zip4j库压缩⽂件⼯具类(⾃适应压缩包编码格式)1. 简单说明:
1. 基于jdk1.8版本编写、测试;
2. 使⽤zip4j1.
3.2;
3. 可解决压缩包解压后,⽂件名乱码;
2. ⽀持情况:
1. ⽀持压缩、解压缩操作;
2. ⽀持加密、不加密操作;
3. ⽀持⾃适应压缩包编码格式;
3. 解决⽂件名乱码核⼼
采⽤的代码
private static String getFileNameCharset(String path)throws ZipException {
String encoding ="GBK";//默认编码
ZipFile zipFile =new ZipFile(path);
List<FileHeader> list = FileHeaders();
for(FileHeader fileHeader : list){
if(fileHeader.isFileNameUTF8Encoded()){
encoding ="UTF-8";
break;
}
}
return encoding;
}
不确定代码,未采⽤此⽅法
private static boolean isMessyCode(String str){
for(int i =0; i < str.length(); i++){
char c = str.charAt(i);
// 当从Unicode编码向某个字符集转换时,如果在该字符集中没有对应的编码,则得到0x3f(即问号字符?)
// 从其他字符集向Unicode编码转换时,如果这个⼆进制数在该字符集中没有标识任何的字符,则得到的结果是0xfffd
if((int) c ==0xfffd){
// 存在乱码
return true;
}
}
return false;
}
5. 具体代码
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.apachemons.lang3.StringUtils;
import net.ZipFile;
import net.ption.ZipException;
import net.del.FileHeader;
import net.del.ZipParameters;
import net.lingala.zip4j.util.Zip4jConstants;
/**
* @author 杨彭伟
* @date 2022-03-03 13:26
*/
public class ZipUtil {
/**
* 使⽤给定密码解压指定的ZIP压缩⽂件到指定⽬录
* <p>
* 如果指定⽬录不存在,可以⾃动创建,不合法的路径将导致异常被抛出
*
* @param zip    指定的ZIP压缩⽂件
* @param dest  解压⽬录
* @param passwd ZIP⽂件的密码
* @return 解压后⽂件数组
* @throws ZipException 压缩⽂件有损坏或者解压缩失败抛出
*/
public static File[]unzipEncrypt(String zip, String dest, String passwd)throws ZipException {        File zipFile =new File(zip);
return unzip(zipFile, dest, passwd);
}
/**
* 使⽤给定密码解压指定的ZIP压缩⽂件到指定⽬录
* <p>
* 如果指定⽬录不存在,可以⾃动创建,不合法的路径将导致异常被抛出
*
* @param zip  指定的ZIP压缩⽂件
* @param dest 解压⽬录
* @return 解压后⽂件数组
* @throws ZipException 压缩⽂件有损坏或者解压缩失败抛出
*/
public static File[]unzip(String zip, String dest)throws ZipException {
File zipFile =new File(zip);
return unzip(zipFile, dest, null);
}
/**
* 使⽤给定密码解压指定的ZIP压缩⽂件到当前⽬录
*
* @param zip    指定的ZIP压缩⽂件
* @param passwd ZIP⽂件的密码
* @return 解压后⽂件数组
* @throws ZipException 压缩⽂件有损坏或者解压缩失败抛出
*/
public static File[]unzipEncrypt(String zip, String passwd)throws ZipException {
File zipFile =new File(zip);
File parentDir = ParentFile();
return unzip(zipFile, AbsolutePath(), passwd);
}
/**
* 解压指定的⽆密码ZIP压缩⽂件到当前⽬录
*
* @param zip 指定的ZIP压缩⽂件
* @return 解压后⽂件数组
压缩包损坏
* @throws ZipException 压缩⽂件有损坏或者解压缩失败抛出
*/
public static File[]unzip(String zip)throws ZipException {
File zipFile =new File(zip);
File parentDir = ParentFile();
return unzip(zipFile, AbsolutePath(), null);
}
/**
* 使⽤给定密码解压指定的ZIP压缩⽂件到指定⽬录
* <p>
* 如果指定⽬录不存在,可以⾃动创建,不合法的路径将导致异常被抛出
*
* @param zipFile 指定的ZIP压缩⽂件
* @param dest    解压⽬录
* @param passwd  ZIP⽂件的密码
* @return 解压后⽂件数组
* @return 解压后⽂件数组
* @throws ZipException 压缩⽂件有损坏或者解压缩失败抛出
*/
private static File[]unzip(File zipFile, String dest, String passwd)throws ZipException {        ZipFile zFile =new ZipFile(zipFile);
zFile.setFileNameCharset(AbsolutePath()));
if(!zFile.isValidZipFile()){
throw new ZipException("压缩⽂件不合法,可能被损坏.");
}
File destDir =new File(dest);
if(destDir.isDirectory()&&!ists()){
destDir.mkdir();
}
if(zFile.isEncrypted()){
if(StringUtils.isNotEmpty(passwd)){
zFile.CharArray());
}else{
throw new ZipException("加密压缩⽂件解压,密码不能为空");
}
}
List<FileHeader> headerList = FileHeaders();
List<File> extractedFileList =new ArrayList<File>();
for(FileHeader fileHeader : headerList){
if(!fileHeader.isDirectory()){
extractedFileList.add(new File(destDir, FileName()));
}
}
File[] extractedFiles =new File[extractedFileList.size()];
return extractedFiles;
}
/**
* 压缩指定⽂件到当前⽂件夹
*
* @param src 要压缩的指定⽂件
* @return 最终的压缩⽂件存放的绝对路径, 如果为null则说明压缩失败.
*/
public static String zip(String src){
return zip(src, null);
}
/**
* 使⽤给定密码压缩指定⽂件或⽂件夹到当前⽬录
*
* @param src    要压缩的⽂件
* @param passwd 压缩使⽤的密码
* @return 最终的压缩⽂件存放的绝对路径, 如果为null则说明压缩失败.
*/
public static String zip(String src, String passwd){
return zip(src, null, passwd);
}
/
**
* 使⽤给定密码压缩指定⽂件或⽂件夹到当前⽬录
*
* @param src    要压缩的⽂件
* @param dest  压缩⽂件存放路径
* @param passwd 压缩使⽤的密码
* @return 最终的压缩⽂件存放的绝对路径, 如果为null则说明压缩失败.
*/
public static String zip(String src, String dest, String passwd){
return zip(src, dest,true, passwd);
}
/
**
* 使⽤给定密码压缩指定⽂件或⽂件夹到指定位置.
* 使⽤给定密码压缩指定⽂件或⽂件夹到指定位置.
* <p>
* dest可传最终压缩⽂件存放的绝对路径,也可以传存放⽬录,也可以传null或者"".<br />
* 如果传null或者""则将压缩⽂件存放在当前⽬录,即跟源⽂件同⽬录,压缩⽂件名取源⽂件名,以.zip为后缀;<br />    * 如果以路径分隔符(File.separator)结尾,则视为⽬录,压缩⽂件名取源⽂件名,以.zip为后缀,否则视为⽂件名.
*
* @param src        要压缩的⽂件或⽂件夹路径
* @param dest        压缩⽂件存放路径
* @param isCreateDir 是否在压缩⽂件⾥创建⽬录,仅在压缩⽂件为⽬录时有效.<br />
*                    如果为false,将直接压缩⽬录下⽂件到压缩⽂件.
* @param passwd      压缩使⽤的密码
* @return 最终的压缩⽂件存放的绝对路径, 如果为null则说明压缩失败.
*/
public static String zip(String src, String dest,boolean isCreateDir, String passwd){
File srcFile =new File(src);
dest =buildDestinationZipFilePath(srcFile, dest);
ZipParameters parameters =new ZipParameters();
parameters.setCompressionMethod(Zip4jConstants.COMP_DEFLATE);// 压缩⽅式
parameters.setCompressionLevel(Zip4jConstants.DEFLATE_LEVEL_NORMAL);// 压缩级别if(!StringUtils.isEmpty(passwd)){
parameters.setEncryptFiles(true);
parameters.setEncryptionMethod(Zip4jConstants.ENC_METHOD_STANDARD);// 加密⽅式
parameters.CharArray());
}
try{
ZipFile zipFile =new ZipFile(dest);
if(srcFile.isDirectory()){
// 如果不创建⽬录的话,将直接把给定⽬录下的⽂件压缩到压缩⽂件,即没有⽬录结构
if(!isCreateDir){
File[] subFiles = srcFile.listFiles();
ArrayList<File> temp =new ArrayList<File>();
Collections.addAll(temp, subFiles);
zipFile.addFiles(temp, parameters);
return dest;
}
zipFile.addFolder(srcFile, parameters);
}else{
zipFile.addFile(srcFile, parameters);
}
return dest;
}catch(ZipException e){
e.printStackTrace();
}
return null;
}
/**
* 根据⽂件路径获取编码格式(解决解压⽂件⽂件名乱码问题)
*
* @param path
* @return
* @throws ZipException
*/
private static String getFileNameCharset(String path)throws ZipException {
String encoding ="GBK";
ZipFile zipFile =new ZipFile(path);
List<FileHeader> list = FileHeaders();
for(FileHeader fileHeader : list){
if(fileHeader.isFileNameUTF8Encoded()){
encoding ="UTF-8";
break;
}
}
return encoding;
}
/**
* 构建压缩⽂件存放路径,如果不存在将会创建
* 传⼊的可能是⽂件名或者⽬录,也可能不传,此⽅法⽤以转换最终压缩⽂件的存放路径
* 传⼊的可能是⽂件名或者⽬录,也可能不传,此⽅法⽤以转换最终压缩⽂件的存放路径
*
* @param srcFile  源⽂件
* @param destParam 压缩⽬标路径
* @return 正确的压缩⽂件存放路径
*/
private static String buildDestinationZipFilePath(File srcFile, String destParam){
if(StringUtils.isEmpty(destParam)){
if(srcFile.isDirectory()){
destParam = Parent()+ File.separator + Name()+".zip";
}else{
String fileName = Name().substring(0, Name().lastIndexOf("."));                destParam = Parent()+ File.separator + fileName +".zip";
}
}else{
// 在指定路径不存在的情况下将其创建出来
createDestDirectoryIfNecessary(destParam);
dsWith(File.separator)){
String fileName ="";
if(srcFile.isDirectory()){
fileName = Name();
}else{
fileName = Name().substring(0, Name().lastIndexOf("."));
}
destParam += fileName +".zip";
}
}
return destParam;
}
/**
* 在必要的情况下创建压缩⽂件存放⽬录,⽐如指定的存放路径并没有被创建
*
* @param destParam 指定的存放路径,有可能该路径并没有被创建
*/
private static void createDestDirectoryIfNecessary(String destParam){
File destDir = null;
dsWith(File.separator)){
destDir =new File(destParam);
}else{
destDir =new File(destParam.substring(0, destParam.lastIndexOf(File.separator)));
}
if(!ists()){
destDir.mkdirs();
}
}
public static void main(String[] args)throws ZipException {
zip("d:\\test\\cc","d:\\test\\cc.zip","11");
unzipEncrypt("d:\\test\\cc.zip","d:\\test\\unzip","11");
}
}
6. 参考⽂章
1. wwwblogs/manhuidhu/p/8027499.html
2. blog.csdn/qq_34122822/article/details/90902815