刚开始处理一个perl应用程序。需要一些建议如何(正确)处理unicode filenames
vs filenames in the file content
- 便携式方式。
以下是几个系统,Windows和Unix世界使用不同的unicode编码(Unixes utf8,Windows - 不知道),但Linux和Mac OS X对文件名的unicode规范化不同。 (OS X - 强制执行NFD,Linux - “通常是”NFC)。
我已经读到的所有建议都说:(始终在应用程序的边界上规范化unicode数据) - 但问题是 - 什么是正确的 - 最便携的方式呢?
问题在于,OS X(创建文本文件时)使用NFC作为内容。我不知道其他系统在使用什么。
所以问题是,制作便携式应用程序和处理文件名的正确方法是什么:
归一化的时间和地点?如何保存utf8文本文件,其内容中包含文件名?
我知道,这里有许多与StacOverflow相关的perl-unicode相关问题。我挖掘了他们中的大多数 - 但仍然不明白什么是“推荐”的做法来处理上面的问题列表。
是否需要制作模块来处理特定的操作系统差异?或者这里是alredy CPAN模块,它们处理文件操作中的操作系统差异?)
有人可以通过推荐的做法向我指出一些好的资源吗?或者我现在想的更简单了?
答案 0 :(得分:2)
据我所知,MS对其文件系统不执行规范化。这意味着如果你计划这种最坏的情况,你就会对其他操作系统有所帮助。
似乎有效的技术是查询操作系统查看的文件。创建一个标准化哈希,键入您选择的规范化形式&包含来自OS的名称作为值。它不优雅,但它的工作原理。
答案 1 :(得分:2)
注意:不鼓励在StackOverflow上请求异地资源。此外,如何规范化Unicode文本的问题过于宽泛。
关于从readdir
或glob
返回的文件名,最好对其进行解码和规范化。请考虑以下代码:
#!/usr/bin/perl
use strict;
use utf8;
use File::Slurp;
use Unicode::Normalize;
binmode(STDOUT, ':utf8');
write_file("Unicode Test - Übersee.txt", "text");
opendir(my $dh, ".") or die($!);
while (my $entry = readdir($dh)) {
utf8::decode($entry);
if ($entry =~ /^Unicode Test - (.*)\.txt/) {
my $word = $1;
print("got $word\n");
print("matches 'Übersee': ", $word eq "Übersee" ? "yes" : "no", "\n");
my $nfc = NFC($word);
print("NFC matches 'Übersee': ", $nfc eq "Übersee" ? "yes" : "no", "\n");
}
}
closedir($dh);
在OS X上,这将输出:
got Übersee
matches 'Übersee': no
NFC matches 'Übersee': yes
这是由于HFS用于规范化文件名的NFD的变化。
从本质上讲,将来自您无法确定其处于正常形式的来源的所有输入标准化。在大多数情况下,您应该使用NFC,因为大多数数据已经在NFC中。