3

背景:

私は 2 台のマシンを持っています。1 台はドイツ語の 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) 関数呼び出しを参照してください。これが問題だと思います。

質問:
OS ファイル システムの文字セットのエンコーディングを教えてください。
ロケールがヘブライ語の OS でドイツ語のファイル名を作成すると、どの文字セットで保存されますか?
この問題を解決するにはどうすればよいですか?

アップデート:

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。2 番目のコード ブロックがどのスコープにも含まれていないと仮定すると、特に a に含まれていないsub場合、@_変数は使用できません。コマンド ライン引数を取得するには、@ARGV配列の使用を検討する必要があります。とにかく、スクリプトのロジックは明確ではありません。エラーメッセージをSTDERRではなくSTDOUTに出力し、ファイル名を「デコード」してから、デコードされていない文字列をブランチに出力しelse、エンコーディングについて偏執的です(これは一般的には良い)が、出力ストリームなどのエンコーディングを指定していません.

于 2012-08-29T14:31:31.973 に答える