繁体   English   中英

使用Java SE6时读取包含特殊字符的ZipEntry

[英]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跟着一个
¨

问题
所以我想知道如何将替换为ü或者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中)将特殊字符转换为分解格式。 所以ü被分解为
从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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM