我想用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
" (希腊字符丢失)
答案 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控制字符(不可映射)。