2

我正在使用 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());
    }
}

它工作正常,但文件名是这样的 在此处输入图像描述

4

4 回答 4

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);
}
于 2016-02-07T05:43:10.620 回答
1

当您使用 zip4j 压缩和提取 zip 文件时,您使用相同的字符集。

(我的测试用例:压缩UTF-8,提取UTF-8,就OK/zip4j 1.3.2)

于 2015-08-10T08:44:57.927 回答
0

在@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);
}
于 2018-01-11T02:45:30.030 回答
0

贝克杨的解决方案确实有效。

对于解压缩中文命名文件并加密密码的人。zip4j 中有一个错误。您必须在 isEncrypted 和 setPassword 之前调用 setFileNameCharset。否则输出编码错误。

而且,只写目录(空目录)有编码问题。并且除了修改源代码外无法修复。

于 2017-08-23T02:14:23.587 回答