背景:
我有两台机器:一台是运行德国Windows 7,另一台是运行英语(带希伯来语语言环境)的Windows 7.
在我的Perl代码中,我正在尝试检查我从德国机器上获得的文件是否存在于我的机器上.
文件名是ßßßzllpoöäüljiznppü.txt
为什么在执行以下代码时失败:
use Encode;
use Encode::locale;
sub UTF8ToLocale
{
my $str = decode("utf8",$_[0]);
return encode(locale, $str);
}
if(!-e UTF8ToLocale($read_file))
{
print "failed to open the file";
}
else
{
print $read_file;
}
当我尝试打开文件时也是如此:
open (wtFile, ">", UTF8ToLocale($read_file));
binmode wtFile;
shift @_;
print wtFile @_;
close wtFile;
文件名在我的java应用程序中从德语转换为utf8,并传递给perl脚本.
perl脚本获取此文件名并将其从utf8转换为系统区域设置,请参阅UTF8ToLocale($read_file)函数调用,我相信这是问题所在.
问题:
你能告诉我什么是OS文件系统charset编码?
当我在OS中创建德语文件名时,语言环境是希伯来语,其中保存了Charset?
我该如何解决这个问题?
更新:
这是我在PC上使用硬编码文件名运行的另一个代码,脚本文件是utf8编码的:
use Encode;
use Encode::locale;
my $string = encode("utf-16",decode("utf8","C:\\TestPerl\\ßßßzllpoöäüljiznppü.txt"));
if (-e $string)
{
print "exists\r\n";
}
else
{
print "not exists\r\n"
}
输出“不存在”.
我也试过不同的字符集:cp1252,cp850,utf-16le,没什么用.
如果我将文件名更改为英语或希伯来语(我的默认语言环境),它可以正常工作.
有任何想法吗?
最佳答案 Windows 7内部使用UTF-16 [需要引用](我不记得字节顺序).因此,您无需转换文件名.但是,如果您通过FAT文件系统(例如旧的USB记忆棒)或其他非Unicode感知文件系统传输文件,这些好处将会丢失.
您正在讨论的区域设置仅影响用户界面的语言和明显的文件夹名称(Program(x86)与Program Files(x86),后者是文件系统中的真实名称).
我可以看到的更大问题是您要传输的文件内容的内部编码,因为某些应用程序可能默认使用不同的编码,具体取决于区域设置.除了在创建文件时显式,否则没有解决方案.坚持使用UTF-8通常是一个好主意.
为什么要用其他工具转换文件名?任何Unicode编码都应该足以进行传输.
您的脚本不起作用,因为您引用了一个名为$read_file的未定义全局变量.假设您的第二个代码块未包含在任何范围内,特别是不在子范围内,则@_变量不可用.要获取命令行参数,您应该考虑使用@ARGV数组.你的脚本逻辑不清楚:你打印错误信息到STDOUT,而不是STDERR,你“解码”文件名,然后在你的分支中打印出未解码的字符串,你对编码很偏执(哪个通常很好)但您没有为输出流等指定编码.