9

我想在 Windows (7) 上使用 .zip 压缩文件ZipOutputStream。问题是文件名(以及文件文件内容)还包含希腊字符(“ ГП0000660040140521_a.txt”、Gamma 和 Pi)。压缩我使用的文件的代码:

ZipOutputStream zipOs = new ZipOutputStream(
    new FileOutputStream("c:\\temp\\test.zip"), Charset.forName("cp737")
);

File sourceFile = new File("C:/Path/To/File/ГП0000660040140521_b.txt");
String entryName = sourceFile.getName().replaceAll("\\\\", "/");
ZipEntry entry = new ZipEntry(entryName);
zipOs.putNextEntry(entry);
...
...

但在最后一行(putNextEntry电话)我得到一个IllegalArgumentException

java.lang.IllegalArgumentException: UNMAPPABLE[1]
at java.util.zip.ZipCoder.getBytes(ZipCoder.java:95)
at java.util.zip.ZipOutputStream.writeLOC(ZipOutputStream.java:407)
at java.util.zip.ZipOutputStream.putNextEntry(ZipOutputStream.java:221)

我认为希腊语和 UTF-8 之间的字符映射一定有什么问题……在文件名中压缩带有希腊字符的文件的正确方法是什么?

编辑

如果我使用“utf-8”作为字符集,则可以创建 zip 文件,但压缩文件的名称错误:“ ðôðƒ0000660040140521_a.txt”(缺少希腊字符)

4

3 回答 3

0

由于我的问题的“味噌”和“kriegax”的评论,我写了这个(迟到的)答案。

如果我没记错的话,我在任何地方都读到过 zip 文件中文件名的 UTF8 支持是 zip 文件的一大弱点(因为 UTF-8 不是 zip 标准的官方支持?!?)。现在可能是现有的 zip 应用程序在文件名中支持 UTF-8。

然而。在我们的例子中,我们可以用“普通”字符(“a...z”)替换希腊字符,因为要压缩的文件是由财务打印机生成的,并且在每种情况下都只包含一个希腊字符:一个“PI”(只是一种解决方法......)。

于 2017-02-27T07:07:02.027 回答
0

问题是,这CP-737确实是一个包含希腊字符的代码页,但是在 Java NIO 中,字符集的名称是x-IBM737. 参照。http://docs.oracle.com/javase/7/docs/technotes/guides/intl/encoding.doc.html

于 2017-03-03T12:39:22.330 回答
0

由于ZipCoder使用了ZipOutputStream一个映射器,该映射器配置为在无法映射字符时总是抛出异常,我最终自己先将 entryName 转换为指定的字符集,然后调用ZipEntry entry = new ZipEntry(entryName). 例如,您可以这样做:

new String(input.getBytes(charset), charset)

这确保了所有不可篡改的字符都被转换为替换字符并且不给出异常。

试试这个,你可能会注意到原始输入中有一些 Unicode 控制字符(不可映射)。

于 2017-03-03T13:36:52.640 回答