使用解决方案更新,请参见底部
要求:
在Java SE 6中处理ZIP文件,其中包含文件名中包含特殊字符的文件。由于(ZIP生产者)的编码不是UTF-8,因此特殊字符被编码。因此,我想将特殊字符更正为正确的代码。
问题:
ZIP包含一个名为abcüabc.txt
的文件。
该条目通过java.util.zip.ZipEntry
处理,当打印出单个字符时,我看到这些字符(字节):
ü
被编码为
u
后跟一个
¨
问题:
所以我想知道如何将u¨
替换为ü
或ue
:
我已经尝试过但没有解决的问题:
name.replaceAll("u\\¨", "ue");
或
name.replaceAll("ü", "ue");
原始源代码(无效):
InputStream is = new FileInputStream(new File("/Users/me/Desktop/test.zip"));
ZipInputStream zipStream = new ZipInputStream(is);
ZipEntry zipEntry = null;
while ((zipEntry = zipStream.getNextEntry()) != null) {
String name = zipEntry.getName(); // reading abcüabc.txt
System.out.println("pos 3: "+name.charAt(3));
System.out.println("pos 4: "+name.charAt(4));
System.out.println("is equal to ¨: "+Character.toString(name.charAt(4)).equals("¨"));
}
输出:
pos 3: u
pos 4:¨
is equal to ¨: false
关于我的环境的说明:
在Mac OS X 10.6.8下生成的Zip Java SE 6:Java HotSpot(TM)64位服务器VM(版本20.12-b01-434,混合模式)
解决方案
显然,ZIP制作人(在我的Mac OSX中)将特殊字符转换为分解格式。因此ü
会被分解为u¨
从ZIP中提取文件名时,我们希望从分解格式转换回组合格式,因此我们只需要在上面的源代码中插入规范化:
InputStream is = new FileInputStream(new File("/Users/me/Desktop/test.zip"));
ZipInputStream zipStream = new ZipInputStream(is);
ZipEntry zipEntry = null;
while ((zipEntry = zipStream.getNextEntry()) != null) {
String name = zipEntry.getName(); // reading abcüabc.txt
System.out.println("pos 3: "+name.charAt(3));
System.out.println("pos 4: "+name.charAt(4));
System.out.println("contains ü: "+name.contains("ü"));
name = Normalizer.normalize(name, Form.NFC);
System.out.println("contains ü: "+name.contains("ü"));
}
输出:
pos 3: u
pos 4:¨
contains ü: false
contains ü: true
答案 0 :(得分:3)
这不是¨
(U+00A8 DIAERESIS),而是U+0308 COMBINING DIAERESIS。
字符以这种方式分割,因为Mac Os将文件名存储在规范化表格D中,它会像这样分解字符。
你可以像这样编曲:
String name = zipEntry.getName();
name = Normalizer.normalize(name, Form.NFC);
的更多信息
diaeresises之间的区别在于他们如何修改或不修改以前的基本字符:
System.out.println( "u" + (char)0xA8); //u¨
System.out.println( "u" + (char)0x0308); //ü
答案 1 :(得分:0)
您可以使用apache ant
解决编码问题。
导入org.apache.tools.zip.*
ZipFile zipFile = new ZipFile(fileName,"you encoding");// you encoding like utf-8
Enumeration emu = zipFile.getEntries();
while(emu.hasMoreElements()){
ZipEntry entry = (ZipEntry) emu.nextElement();
// do something
}
Ant项目不提供在线文档,这是另一个文档http://api.dpml.net/ant/1.7.0/