Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/386.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java &引用;IllegalArgumentException:UNMAPPABLE[1]”;在压缩带有希腊字符的文件时_Java_Character Encoding_Zipoutputstream - Fatal编程技术网

Java &引用;IllegalArgumentException:UNMAPPABLE[1]”;在压缩带有希腊字符的文件时

Java &引用;IllegalArgumentException:UNMAPPABLE[1]”;在压缩带有希腊字符的文件时,java,character-encoding,zipoutputstream,Java,Character Encoding,Zipoutputstream,我想用ZipOutputStream在Windows(7)上压缩一个文件。问题在于,文件名(以及文件内容)也包含希腊字符(“ГП0000660404140521_a.txt”,Gamma和Pi)。我使用的压缩文件的代码: ZipOutputStream zipOs = new ZipOutputStream( new FileOutputStream("c:\\temp\\test.zip"), Charset.forName("cp737") ); File sourceFile =

我想用
ZipOutputStream
在Windows(7)上压缩一个文件。问题在于,文件名(以及文件内容)也包含希腊字符(“
ГП0000660404140521_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”作为字符集,则可以创建压缩文件,但压缩文件的名称是错误的:“
ððƒ0000660404140521_a.txt
”(希腊字符缺失)

我写这个(晚些时候)答案是因为我的问题中有“miso”和“kriegax”的注释

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


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

问题是,
CP-737
确实是一个包含希腊字符的代码页,但是在JavaNIO中,字符集的名称是
x-IBM737
。Cf.

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

new String(input.getBytes(charset), charset)
这可确保将所有不兼容字符转换为替换字符,并且不会给出任何异常


尝试此方法,您可能会注意到原始输入中的一些Unicode控制字符(不可映射)。

createZipEntry方法的作用是什么?@agad:我的错误!我已经更正了代码。谢谢。当你说名字“错”的时候,你到底是怎么验证的?您使用哪个工具来检查ZIP文件,并且您确定该工具使用的编码与您创建文件时使用的编码相同吗?我使用Windows的文件资源管理器打开它。您的意思是,文件名是正确的,但Windows资源管理器显示的文件名是错误的吗?但是为什么Windows文件资源管理器显示原始文件的字符是正确的呢?在Java代码中使用UTF-8时,我无法复制这个问题。我在一个德国Windows(cp850)上进行了尝试,创建了一个文件όνομαuαρχείον.txt,然后从Java8压缩它。ZIP文件中的文件名是正确的,我只在代码中使用UTF-8以外的东西时遇到问题。所以我需要更多关于你是如何做到这一点的信息。ZIP的实际问题是它没有任何关于用于编码文件名的实际编码(字符集)的元信息。