我正在创建一个包含非ascii字符的文件。
如果以0
作为参数调用,下面的脚本可以正常工作,但当使用1
调用时,它会死亡。
错误信息是open: Invalid argument at C:tempfilename.pl line 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: $filenamen";
close $fh;
我可能错过了一些对其他人来说很明显的东西,但我找不到,所以我很感激任何指向解决这个问题的指针。
首先,说"UTF-8字符"很奇怪。UTF-8可以编码任何Unicode字符,因此UTF-8字符集就是Unicode字符集。这意味着您希望创建文件名包含Unicode字符的文件,更具体地说,是不在cp1252中的Unicode字符。
我以前在PerlMonks上回答过这个问题。答案抄在下面
Perl将文件名视为不透明的字节串。这意味着文件名需要按照"区域设置"的编码(ANSI代码页)进行编码。
在Windows中,代码页1252
通常被使用,因此编码通常是cp1252
.*然而,cp1252
不支持泰米尔语和印地语字符[或"☺"]。
Windows也提供了一个"Unicode"又名"Wide"接口,但是Perl不提供使用内置的访问它**。不过,您可以使用Win32API::File的CreateFileW
。在IIRC中,您仍然需要自己编码文件名。如果是这样,可以使用UTF-16le
作为编码。
前面提到的Win32::Unicode似乎为您处理了使用Win32API::File的一些肮脏工作。我也建议从这个开始。
& # 42;本;代码页由GetACP
系统调用返回(作为一个数字)。前置" cp
"以获得编码
& # 42; & # 42;本;Perl对Windows的支持在某些方面很糟糕。
下面的程序在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 theren";
close(FILE);
不需要对文件名进行编码(至少在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: $filenamen";
close $fh;
HTH,保罗