背景:
我有两台机器:一台是运行德国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,没什么用。 如果我将文件名更改为英语或希伯来语(我的默认语言环境),它可以正常工作。 有什么想法吗?
答案 0 :(得分:2)
Windows 7在内部使用 UTF-16 [引用需要](我不记得字节顺序)。因此,您无需转换文件名。但是,如果您通过FAT文件系统(例如旧的USB记忆棒)或其他非Unicode感知文件系统传输文件,这些好处将会丢失。
您正在谈论的区域设置设置仅影响用户界面的语言和明显的文件夹名称(Programme (x86)
与Program Files (x86)
,后者是真实姓名在文件系统中。)
我可以看到的更大问题是您要传输的文件内容的内部编码,因为某些应用程序可能默认使用不同的编码,具体取决于区域设置。除了在创建文件时显式,否则没有解决方案。坚持使用UTF-8通常是一个好主意。
为什么要用其他工具转换文件名?任何Unicode编码都应该足以进行传输。
您的脚本不起作用,因为您引用了一个名为$read_file
的未定义全局变量。假设您的第二个代码块未包含在任何范围内,尤其不在sub
中,则@_
变量不可用。要获取命令行参数,您应该考虑使用@ARGV
数组。你的脚本逻辑不清楚:你打印错误信息到STDOUT,而不是STDERR,你“解码”文件名,然后打印出你else
- 分支中未解码的字符串,你是偏执狂关于编码(通常很好)但你没有为输出流等指定编码。