3

背景

我有 2 台机器:一台运行德语 windows 7,我的 PC 运行英语(使用希伯来语区域设置)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) 函数调用,我相信这就是问题所在。

问题:
你能告诉我什么是操作系统文件系统字符集编码吗?
当我在操作系统中创建德语文件名时,语言环境是希伯来语,其中保存了字符集?
我该如何解决这个问题?

更新:

这是我在 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,没有任何效果。如果我将文件名更改为英语或希伯来语(我的默认语言环境),它可以工作。有任何想法吗?

4

1 回答 1

2

Windows 7 在内部使用UTF-16 [需要引用](我不记得字节顺序)。因此,您不需要转换文件名。但是,如果您通过 FAT 文件系统(例如旧的 USB 记忆棒)或其他不支持 Unicode 的文件系统传输文件,这些好处将丢失。

您正在谈论的区域Programme (x86)设置仅影响用户界面的语言和明显的文件夹名称(与Program Files (x86)后者是文件系统中的真实名称相比)。

我可以看到的更大问题是您要传输的文件内容的内部编码,因为某些应用程序可能会根据语言环境默认使用不同的编码。除了在创建文件时明确说明之外,没有解决方案。坚持使用 UTF-8 通常是个好主意。

为什么要使用其他工具转换文件名?任何 Unicode 编码都应该足以传输。


您的脚本不起作用,因为您引用了一个未定义的全局变量$read_file. 假设您的第二个代码块未包含在任何范围内,尤其是未包含在 a 中sub,则该@_变量不可用。要获取命令行参数,您应该考虑使用@ARGV数组。无论如何,您的脚本的逻辑都不清楚:您将错误消息打印到 STDOUT,而不是 STDERR,您“解码”文件名​​,然后在您的else-branch 中打印出未解码的字符串,您对编码偏执(这是通常很好)但您没有为输出流等指定编码。

于 2012-08-29T14:31:31.973 回答