我正在努力创建一个包含非ascii字符的文件。
以下脚本可以正常工作,如果使用0
作为参数调用,但在使用1
调用时会死亡。
错误消息 open:C:\ temp \ filename.pl第15行的参数无效。
脚本在cmd.exe
内启动。
我希望它能够编写一个名称相同的文件(取决于参数)äöü.txt
或äöü☺.txt
。但我无法创建包含笑脸的文件名。
use warnings;
use strict;
use Encode 'encode';
# Text is stored in utf8 within *this* file.
use utf8;
my $with_smiley = $ARGV[0];
my $filename = 'äöü' .
($with_smiley ? '☺' : '' ).
'.txt';
open (my $fh, '>', encode('cp1252', $filename)) or die "open: $!";
print $fh "Filename: $filename\n";
close $fh;
我可能错过了一些对他人来说很明显的东西,但是我找不到,所以我很欣赏任何解决这个问题的指针。
答案 0 :(得分:12)
首先,说“UTF-8字符”很奇怪。 UTF-8可以编码任何Unicode字符,因此UTF-8字符集是Unicode字符集。这意味着您要创建名称包含Unicode字符的文件,更具体地说,是不在cp1252中的Unicode字符。
我过去在PerlMonks上answered这个。答案复制如下。
Perl将文件名视为不透明的字节字符串。这意味着文件名需要根据“语言环境”的编码(ANSI代码页)进行编码。
在Windows中,常用代码页1252
,因此编码通常为cp1252
。*但是,cp1252
不支持泰米尔语和印地语字符[或“☺” ]
Windows还提供“Unicode”又称“宽”接口,但Perl不提供使用内置**的访问权限。不过,您可以使用Win32API::File的CreateFileW
。 IIRC,你还需要自己编码文件名。如果是,则使用UTF-16le
作为编码。
前面提到Win32::Unicode似乎处理了使用Win32API::File的一些肮脏工作。我也建议从那开始。
* - GetACP
系统调用返回代码页(作为数字)。前置“cp
”以获取编码。
** - Perl对Windows的支持在某些方面很糟糕。
答案 1 :(得分:1)
以下在Windows 7上运行,ActiveState Perl。它将“hello there”写入名称中带有希伯来字符的文件:
#-----------------------------------------------------------------------
# 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 :(得分:-1)
无需编码文件名(至少不在linux上)。这段代码适用于我的linux系统:
use warnings;
use strict;
# Text is stored in utf8 within *this* file.
use utf8;
my $with_smiley = $ARGV[0] || 0;
my $filename = 'äöü' .
($with_smiley ? '?' : '' ).
'.txt';
open my $fh, '>', $filename or die "open: $!";
binmode $fh, ':utf8';
print $fh "Filename: $filename\n";
close $fh;
HTH,保罗