[英]zip4j setFileNameCharset not working
我正在使用zip4j解压缩文件,而文件名charset却有问题。 这是我的代码,
try {
ZipFile zipFile = new ZipFile(source);
if (zipFile.isEncrypted()) {
zipFile.setPassword(password);
}
System.out.println(System.getProperty("file.encoding"));
zipFile.setFileNameCharset("UTF-8");
zipFile.extractAll(destination);
} catch (ZipException e) {
System.out.println(e.getMessage());
}
}
一切正常,但是文件名是这样的
当您使用zip4j压缩和解压缩zip文件时,您将使用相同的字符集。
(我的测试用例:压缩UTF-8,解压缩UTF-8,就可以了/ zip4j 1.3.2)
如果要提取由其他软件创建的zip文件。 文件名的字符集可能是系统默认的字符集(例如GBK,Shift-JIS或其他字符集...)
在这种情况下,如果源文件名之一包含该字符集中不存在的Unicode字符。 该ZipEntry中的文件名已转换为UTF-8。
要提取这种zip文件,必须使用自定义代码一个接一个地转换文件名。
ZipFile zipFile = new ZipFile("input.zip");
UnzipParameters param = new UnzipParameters();
zipFile.setFileNameCharset("ISO8859-1");
List list = zipFile.getFileHeaders();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
FileHeader fh = (FileHeader) iterator.next();
byte[] b = fh.getFileName().getBytes("ISO8859-1");
String fname = null;
try {
fname = new String(b, "UTF-8");
if (fname.getBytes("UTF-8").length != b.length) {
fname = new String(b,"GBK");//most possible charset
}
} catch (Throwable e) {
//try other charset or ...
System.err.println("Invalid file name: "+fname);
}
z.extractFile(fh, dir, param, fname);
}
Beck Yang的解决方案确实有效。
对于用密码加密解压缩中文命名文件的人。 zip4j中有一个错误。 您必须在isEncrypted和setPassword之前调用setFileNameCharset。 否则输出编码错误。
而且,仅写入目录(空目录)存在编码问题。 并且除了修改源代码外无法修复。
在@Beck Yang的基础上,只需使用apache tika
库并自动检测字符集,您就可以使用任何语言。
import org.apache.tika.parser.txt.CharsetDetector;
...
ZipFile zipFile = new ZipFile("input.zip");
UnzipParameters param = new UnzipParameters();
zipFile.setFileNameCharset("ISO8859-1");
List list = zipFile.getFileHeaders();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
FileHeader fh = (FileHeader) iterator.next();
byte[] b = fh.getFileName().getBytes("ISO8859-1");
String fname = null;
try {
CharsetDetector charDetect = new CharsetDetector();
charDetect.setText(b);
String charSet = charDetect.detect().getName();
fName = new String(b, charSet);
} catch (Throwable e) {
fName = fh.getFileName();
}
z.extractFile(fh, dir, param, fname);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.