7

を使用してソケット経由でデータを受信する Java アプリケーションがありますInputStreamReadergetEncodingメソッドから「Cp1252」が報告されます。

/* java.net. */ Socket Sock = ...;
InputStreamReader is = new InputStreamReader(Sock.getInputStream());
System.out.println("Character encoding = " + is.getEncoding());
// Prints "Character encoding = Cp1252"

これは、システムがコード ページとして報告するものと必ずしも一致しません。例えば:

C:\>chcp
アクティブ コード ページ: 850

アプリケーションは、バイト 0x81 を受け取る場合があります。これは、コード ページ 850 で文字 を表しますü。プログラムはそのバイトをコード ページ 1252 で解釈しますが、この値では文字が定義されていないため、代わりに疑問符が表示されます。

アプリケーションを起動するバッチ ファイルに別のコマンド ライン オプションを追加することで、コード ページ 850 を使用しているある顧客のために、この問題を回避することができました。

java.exe -Dfile.encoding=Cp850 ...

もちろん、すべての顧客がコード ページ 850 を使用しているわけではありません。基盤となる Windows システムと互換性のあるコード ページを Java で使用するにはどうすればよいですか? 私の好みは、Javaコードをそのままにして、バッチファイルに入れることができるものです。

ENC=...
java.exe -Dfile.encoding=%ENC% ...
4

4 に答える 4

7

で使用されるデフォルトのエンコーディングcmd.exeCp850(または、OS にネイティブな「OEM」CP であれば何でも) です。システムエンコーディングはCp1252(または「ANSI」CPがOSにネイティブであるもの)です。詳細はこちらコンソール エンコーディングを検出する 1 つの方法は、ネイティブ コードを介して行うことです(現在のコンソール エンコーディングについては GetConsoleOutputCP を参照てください。デフォルトの "ANSI" エンコーディングについてはGetACPを参照してください)。

スイッチを介してエンコーディングを-D変更すると、リダイレクトされた stdout/stdin/stderr を含むすべてのデフォルトのエンコーディング メカニズムに影響します。これは理想的なソリューションではありません。

コンソールをシステム ANSI コードページに設定できるこの WSH スクリプトを思いつきましたが、プログラムで TrueType フォントに切り替える方法がわかりませんでした。

'file:  setacp.vbs
'usage: cscript /Nologo setacp.vbs
Set objShell = CreateObject("WScript.Shell")
'replace ACP (ANSI) with OEMCP for default console CP
cp = objShell.RegRead("HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001" &_
                              "\Control\Nls\CodePage\ACP")
WScript.Echo "Switching console code page to " & cp
objShell.Exec "chcp.com " & cp

(これは私の最初の WSH スクリプトなので、欠陥がある可能性があります。レジストリの読み取りアクセス許可に詳しくありません。)

TrueType フォントを使用することは、 で ANSI/Unicode を使用するためのもう 1 つの要件ですcmd.exe。時間が許せば、より良いフォントへのプログラムによる切り替えを検討します。

于 2009-08-26T21:36:31.093 に答える
5

chcpコマンドから返されるコードページの値が必要な値を返す場合は、次のコマンドを使用してコードページを取得できます。

C:\>for /F "Tokens=4" %I in ('chcp') Do Set CodePage=%I

これにより、変数CodePageがchcpから返されたコードページ値に設定されます。

C:\>echo %CodePage%
437

この値の前にCpを付けることで、batファイルでこの値を使用できます。

C:\>echo Cp%CodePage%
Cp437

これをbatファイルに入れる場合、最初のコマンドの%I値を%%Iに置き換える必要があります

于 2009-08-26T20:06:12.557 に答える
5

コードスニピットに関して、正しい答えは、正しいコード変換を行うInputStreamReaderの適切なコンストラクターを使用することです。そうすれば、システムのデフォルトのエンコーディングが何であるかは関係ありません。ソケットで取得しているものに対応する正しいエンコーディングを取得していることがわかります。

次に、システムエンコーディングに依存するのではなく、必要に応じてファイルを書き出すときにエンコーディングを指定できますが、もちろん、そのシステムでファイルを開くときに問題が発生する可能性がありますが、最新のWindowsシステムはUTF-8をサポートしているため、必要に応じて、ファイルをUTF-8で書き出すことができます(内部的には、Javaはすべての文字列を16ビットのユニコードとして表します)。

これは一般的に「正しい」ソリューションであり、基盤となるシステムの最大範囲と最も互換性があると思います。

于 2009-08-26T19:38:36.730 に答える
4

Windows には、2 つのアクティブなコードページがあるという複雑な問題があります。あなたの例では、1252 と 850 の両方が正しいですが、プログラムの実行方法によって異なります。GUI アプリケーションの場合、Windows は ANSI コード ページを使用します。これは、西ヨーロッパ言語では通常 1252 になります。ただし、コマンド ラインでは、同じロケールでは 850 である OEM コードページが報告されます。

于 2009-08-26T20:01:06.310 に答える