" IllegalArgumentException:UNMAPPABLE [1]"同时用希腊字符压缩文件

时间:2014-05-21 12:51:21

标签: java character-encoding zipoutputstream

我想用ZipOutputStream在Windows(7)上压缩文件。问题是文件名(以及文件文件Content)也包含希腊字符(" ГП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" (希腊字符丢失)

3 个答案:

答案 0 :(得分:0)

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

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

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

答案 1 :(得分:0)

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

答案 2 :(得分:0)

由于ZipCoder使用的ZipOutputStream使用配置为在无法映射字符时始终抛出异常的映射器,因此我最终将entryName首先转换为指定的字符集,然后由致电ZipEntry entry = new ZipEntry(entryName)。你可以这样做:

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

这可确保将所有不可阻塞的字符转换为替换字符,并且不会出现异常。

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