gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-29 05:50:12 25 4
gpt4 key购买 nike

更新了解决方案,见底部

要求:
在 Java SE 6 中处理 ZIP 文件,该文件包含文件名中带有特殊字符的文件。由于(ZIP 制作者的)编码不是 UTF-8,特殊字符会被编码。因此,我想将特殊字符更正为正确的代码。

问题:
ZIP 包含一个名为 abcüabc.txt 的文件。该条目通过 java.util.zip.ZipEntry 进行处理,当打印出单个字符时,我看到这些字符(字节):

ü 被编码为
u 后接 a
¨

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

字符被这样拆分是因为 Mac Os 将文件名存储在 Normalization Form D 中,它会像这样分解字符。

你可以这样组合它:

String name = zipEntry.getName(); 
name = Normalizer.normalize(name, Form.NFC);

更多关于 normalization forms

分音符之间的区别在于它们如何修改或不修改前一个基本字符:

    System.out.println( "u" + (char)0xA8); //u¨
System.out.println( "u" + (char)0x0308); //ü

关于java - 使用 Java SE6 读取包含特殊字符的 ZipEntry,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14196408/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com