如何使用Perl在Windows中创建unicode文件名

时间:2011-05-13 13:18:12

标签: windows perl unicode

我有以下代码

use utf8;
open($file, '>:encoding(UTF-8)', "さっちゃん.txt") or die $!;
print $file "さっちゃん";

但我得到的文件名为ã•ãããããã,ãã,ã。,“。txt

我想知道是否有一种方法可以让我的工作正如我所期望的那样(意思是我有一个unicode文件名),而不需要使用Win32 :: API,Win32API :: *或移动到另一个平台并使用Samba共享以修改文件。

目的是确保我们没有任何需要加载的Win32特定模块(甚至是有条件的)。

3 个答案:

答案 0 :(得分:6)

Perl将文件名视为不透明的字节字符串。它们需要根据“语言环境”的编码(ANSI代码页)进行编码。

在Windows中,通常为cp1252。它由GetACP系统调用返回。 (前缀“cp”)。但是,cp1252不支持日文字符。

Windows还提供“Unicode”又称“宽”接口,但Perl不提供使用内置*的访问权限。但是,您可以使用Win32API :: File的CreateFileW。 IIRC,你还需要自己编码文件名。如果是,则使用UTF-16le作为编码。

* - Perl对Windows的支持在某些方面很糟糕。

答案 1 :(得分:1)

以下使用Activestate Perl在Windows 7上生成一个单独的文件名。

#-----------------------------------------------------------------------
# Unicode file names on Windows using Perl
# Philip R Brenan at gmail dot com, Appa Apps Ltd, 2013
#-----------------------------------------------------------------------

use feature ":5.16";
use Data::Dump qw(dump);
use Encode qw/encode decode/;
use Win32API::File qw(:ALL);

# Create a file with a unicode name

my $e  = "\x{05E7}\x{05EA}\x{05E7}\x{05D5}\x{05D5}\x{05D4}".
         "\x{002E}\x{0064}\x{0061}\x{0074}\x{0061}"; # File name in UTF-8
my $f  = encode("UTF-16LE", $e);  # Format supported by NTFS 
my $g  = eval dump($f);           # Remove UTF ness
   $g .= chr(0).chr(0);           # 0 terminate string
my $F  = Win32API::File::CreateFileW
 ($g, GENERIC_WRITE, 0, [], OPEN_ALWAYS, 0, 0); # Create file via Win32API
say $^E if $^E;                   # Write any error message

# Write to the file

OsFHandleOpen(FILE, $F, "w") or die "Cannot open file";
binmode FILE;                       
print FILE "hello there\n";       
close(FILE);

答案 2 :(得分:0)

使用Encode::Locale

use utf8;
use Encode::Locale;
use Encode;

open($file, '>:encoding(UTF-8)', encode(locale_fs => "さっちゃん.txt") ) or die $!;
print $file "さっちゃん";