【发布时间】:2021-10-26 16:20:57
【问题描述】:
我有一个包含 Unicode 字符的 perl 字符串,我想用这个字符串作为文件名创建一个文件。无论使用何种语言环境,它都应该适用于 Windows、Linux 和 Mac。 这是我的代码:
use strict;
use warnings FATAL => 'all';
use Encode::Locale;
use Encode;
# ファイル.c
my $file = "\x{30D5}\x{30A1}\x{30A4}\x{30EB}.c";
$file = encode(locale_fs => $file);
open(my $filehdl, '>', $file) or die("Unable to create file: $!");
close($filehdl);
我使用encode 函数,因为根据这个answer:
Perl 将文件名视为不透明的字节字符串。它们需要按照您的“区域设置”的编码(ANSI 代码页)进行编码。
但是,此代码失败并出现以下错误:
无法创建文件:.\perl.pl 第 15 行的参数无效。
我更深入地了解了encode如何对字符串进行编码:
my $rep = sprintf '%v02X', $file;
print($rep);
打印出来:
3F.3F.3F.3F.2E.63
在我当前的语言环境 (CP-1252) 中,它对应于 ????.c。我们可以看到每个 Unicode 字符都被一个问号代替了。
我认为这里有问号是正常的,因为我的字符串中的字符无法使用 CP-1252 编码表示。
所以,我的问题是:有没有办法创建一个名称包含 Unicode 字符的文件?
【问题讨论】:
-
只是,你不能。不能保证文件系统支持 Unicode,并且每个操作系统都有允许使用哪些字符的特殊情况。我们还没有准备好。
-
@GiacomoCatenazzi 你的意思是,即使我确定我的操作系统可以创建文件(如果我直接使用文件资源管理器就是这种情况),我也无法为此编写可移植代码对吧?
-
不清楚你想象的应该是什么意思。如果操作系统和文件系统支持 UTF-8,那么使用它应该很简单;但当然,他们这样做的假设是不可移植的。
-
我会很惊讶有一种可移植的方式(并且在同一操作系统中也可移植,但不同的用户、不同的文件系统 [例如 USB 记忆棒、外部磁盘])等)。但是让我们看看是否有人有解决方案。
-
如果您使用的是 Windows,另请参阅 Win32::Unicode::File 和 this 问题