使用的zip4j版本号:
implementation "net.lingala.zip4j:zip4j:2.11.1"
最近因项目需要用到zip压缩和解压,包含密码压缩包,用到了zip4j这个库,在测试的过程中,发现分别使用mac、windows压缩的zip包,在解压时会出现乱码情况,这个问题的主要原因是,在解压时设置的编码格式不对,导致的乱码。
解决方案:
1、因为zip4j 默认UTF-8编码,如果是windows压缩包(windows默认是GBK编码),解压后会出现乱码。
2、基于上,只要判断文件名中有乱码,设置编码格式为GBK,即可解决。
代码如下:
public static void unZip(String srcFilePath, String destFilePath) {
unZip(srcFilePath, destFilePath,"");
}
public static void unZip(String srcFilePath, String destFilePath, String password) {
try {
net.lingala.zip4j.ZipFile zFile = new net.lingala.zip4j.ZipFile(srcFilePath);
zFile.setCharset(StandardCharsets.UTF_8);
List<FileHeader> headers = zFile.getFileHeaders();
if (isRandomCode(headers)) {//判断文件名是否有乱码,有乱码,将编码格式设置成GBK
zFile.close();
zFile = new net.lingala.zip4j.ZipFile(srcFilePath);
zFile.setCharset(Charset.forName("GBK"));
}
if (!zFile.isValidZipFile()) {
throw new ZipException("压缩文件不合法,可能被损坏.");
}
if (zFile.isEncrypted() && !TextUtils.isEmpty(password)) {//加密zip,且输入的密码不为空,直接进行解密。
zFile.setPassword(password.toCharArray());
}
File destDir = new File(destFilePath);
if (!destDir.getParentFile().exists()) {
destDir.mkdir();
}
zFile.extractAll(destFilePath);
}catch (Exception exception){
exception.printStackTrace();
}
}
//待解压的文件名是否乱码
private static boolean isRandomCode(List<FileHeader> fileHeaders) {
for (int i = 0; i < fileHeaders.size(); i++) {
FileHeader fileHeader = fileHeaders.get(i);
boolean canEnCode = Charset.forName("GBK").newEncoder().canEncode(fileHeader.getFileName());
if (!canEnCode) {//canEnCode为true,表示不是乱码。false.表示乱码。是乱码则需要重新设置编码格式
return true;
}
}
return false;
}