当前位置: 首页 > 面试题库 >

File.listFiles()使用JDK 6处理Unicode名称(Unicode规范化问题)

熊烨
2023-03-14
问题内容

在OS X和Linux上列出Java6中的目录内容时,我正遇到一个奇怪的文件名编码问题:与File.listFiles()和相关的方法似乎以与系统其余部分不同的编码返回文件名。

请注意,导致这些问题的不仅仅是显示这些文件名。我主要感兴趣的是将文件名与远程文件存储系统进行比较,因此我更关心名称字符串的内容,而不是用于打印输出的字符编码。

这是一个演示程序。它创建一个具有Unicode名称的文件,然后打印出从直接创建的文件获得的文件名的 URL编码
版本,以及在父目录下列出的相同文件(您应该在空目录中运行此代码)。结果显示该File.listFiles()方法返回的不同编码。

    String fileName = "Trîcky Nåme";
    File file = new File(fileName);
    file.createNewFile();
    System.out.println("File name: " + URLEncoder.encode(file.getName(), "UTF-8"));

    // Get parent (current) dir and list file contents
    File parentDir = file.getAbsoluteFile().getParentFile();
    File[] children = parentDir.listFiles();
    for (File child: children) {
        System.out.println("Listed name: " + URLEncoder.encode(child.getName(), "UTF-8"));
    }

这是在系统上运行此测试代码时得到的。注意%CCvs %C3字符表示。

OS X雪豹:

File name: Tri%CC%82cky+Na%CC%8Ame
Listed name: Tr%C3%AEcky+N%C3%A5me

$ java -version
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02-279-10M3065)
Java HotSpot(TM) 64-Bit Server VM (build 16.3-b01-279, mixed mode)

KUbuntu Linux(在同一OS X系统上的VM中运行):

File name: Tri%CC%82cky+Na%CC%8Ame
Listed name: Tr%C3%AEcky+N%C3%A5me

$ java -version
java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8.1) (6b18-1.8.1-0ubuntu1)
OpenJDK Client VM (build 16.0-b13, mixed mode, sharing)

我曾尝试过各种黑客获得字符串的同意,包括设置file.encoding系统属性和各种LC_CTYPELANG环境变量。没有任何帮助,我也不想求助于此类黑客。

与这个(有点相关?)问题不同,我可以从列出的文件中读取数据,尽管名称是奇数


问题答案:

使用Unicode,可以使用多种有效的方式来表示同一字母。您在“棘手的名称”中使用的字符是“带小圆音的拉丁字母i”和“带圆环的拉丁字母a”。

您说“注意%CC%C3字符的表示形式”,但是仔细看,您看到的是序列

i 0xCC 0x82 vs. 0xC3 0xAE
a 0xCC 0x8A vs. 0xC3 0xA5

That is, the first is letter i followed by 0xCC82 which is the UTF-8
encoding of theUnicode\u0302
“combining circumflex accent” character while the second is UTF-8 for
\u00EE “latin
small letter i with circumflex”. Similarly for the other pair, the first is
the letter a followed by 0xCC8A the “combining ring above” character and the
second is “latin small letter a with ring above”. Both of these are valid
UTF-8 encodings of valid Unicode character strings, but one is in “composed”
and the other in “decomposed” format.

OS X HFSPlus卷将字符串(例如文件名)存储为“完全分解”。Unix文件系统实际上是根据文件系统驱动程序选择存储方式来存储的。您不能在不同类型的文件系统之间做任何笼统的声明

有关组合形式与分解形式的一般性讨论,请参见Wikipedia上有关Unicode等价的文章,其中特别提到了OSX。

有关转换表格的信息,请参阅Apple的Tech Q&A
QA1235(不幸的是,在Objective-C中)。

Apple的java-dev邮件列表上的最新电子邮件线程可能会对您有所帮助。

基本上,您需要先将分解形式标准化为组合形式,然后才能比较字符串。



 类似资料:
  • 问题内容: 在Python中,是否存在标准化unicode字符串的标准方法,以使其仅包含可用于表示它的最简单的unicode实体? 我的意思是,一些东西,想翻译的顺序来? 查看问题出在哪里: 但现在: 当然,我可以遍历所有字符并进行手动替换等,但是效率不高,我敢肯定我会错过一半的特殊情况,并且会犯错误。 问题答案: 该模块提供一个功能,您要标准化为NFC格式: NFC或“普通形式组合”返回组成的字

  • 我了解批次归一化有助于更快的训练,将激活转向单位高斯分布,从而解决梯度消失问题。批次规范行为在训练(使用每个批次的平均值/var)和测试时间(使用训练阶段的最终运行平均值/var)中的应用不同。 另一方面,实例归一化作为对比度归一化,如本文所述https://arxiv.org/abs/1607.08022。作者提到,输出样式化的图像不应依赖于输入内容图像的对比度,因此实例规范化有助于实现。 但是

  • 我用java运行代码,Unicode字符可以显示正确,但当我用maven(Mvn clean test)运行代码时,Unicode字符显示不正确。我有用户范围报告和扩展报告显示日志的Unicode字符也不正确 实际结果:?y l v?n b?n ti?ng vi?t 预期结果:Derâlàvăn b n tiéng viét

  • 在JasperReports中,处理文本需要一些专用工具来处理字符表示和文本格式化属性。 可以将任何文本视为具有特定表示结构的字符序列。 文本外观包括布局(和段落)和字体设置。 但在大多数情况下,文本布局保持不变,在不同的语言环境中运行报表时,字体设置可能会更改。 我们知道不同的语言在特定的字符表示方面需要不同的字符集。 因此,使用文本意味着使用字体。 但是,有关如何在JasperReports中

  • 我在Perl中有一个旧版应用程序,最有可能处理以编码的XML,并且需要将该XML的某些数据存储在某个数据库中,该数据库出于历史原因使用。是的,此设置不能支持Unicode标准的所有可能字符,但在实践中,我不需要这样做,并且可以尝试合理的兼容性。 当前的具体问题是一个包含(>)的文件,这使得Perl将Unicode字符串的现有编码中断为 “\x{0308}”未映射到cp1252 我使用Unicode

  • Ever wonder about that mysterious Content-Type tag? You know, the one you're supposed to put in HTML and you never quite know what it should be? 有没有好奇那个神奇的Content-Type标签?你知道那个标签要放到HTML页面里面去,但是你却从来没搞清楚