[英]Reading ZipEntry containing special characters while using Java SE6
更新解决方案,请参阅底部
要求 :
在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
关于我的环境的说明 :
Zip在Mac OS X 10.6.8下生成
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
那不是¨
( U + 00A8 DIAERESIS ),而是U + 0308组合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); //ü
你可以使用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项目不提供在线文档,这里是另一个doc http://api.dpml.net/ant/1.7.0/
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.