私はこの問題を抱えており、数日間検索に失敗し、回避策を試みました。
私は現在、osx および Windows コンピューター上で、jnlp/webstart によって配布されている内部 Java スイング プログラムを持っています。これは、とりわけ、WebDav からいくつかのファイルをダウンロードします。
最近、OSX 10.8 と Java 7 を搭載したテスト マシンで、アクセント付き文字を含むファイル名とディレクトリ名がクエスチョン マークに置き換えられ始めました。
Java のバージョンが 7 より前の OSX では問題ありません。
例 :
XXXYYYY_è_ABCD/
になる
XXXYYYY_?_ABCD/
元の文字列でjava.text.Normalizer (NFD、NFC、NFKD、NFKC) を使用すると、結果は異なりますが、それでも間違っています。
XXXYYYY_e?_ABCD/
また
XXXYYYY_e_ABCD/
[oracle.com の andrew.brygin] と [gmail.com の mik3hall] の間のやり取りから、
はい、file.encoding は jvm が実行されているロケールに基づいて設定されます。java vm を xxxx.UTF-8 ロケールで実行する場合、file.encoding は UTF-8 である必要があり、MacRoman に設定すると問題が発生します。したがって、Oracle/OpenJDK7 は正しく動作すると思います。そうは言っても、Andrew Thompson が指摘したように、以前のすべての Apple JDK リリースが英語/UTF-8 ロケールの file.encoding として MacRoman を使用している場合、ここに「互換性」の問題があり、リリース ノートに何かを記載する価値があるかもしれません。 Oracle/OpenJDK MacOS ユーザー a が頭を上げます。
Joni Salonenブログ ( java-and-file-names-with-invalid-characters )から、私はそれを知っています:
Java が「デフォルトの文字エンコーディング」を使用してバイナリ データを文字列に変換することはおそらくご存知でしょう。別のエンコーディングを使用してテキストを読み書きするには、InputStreamReader または OutputStreamWriter を使用できます。しかし、API の奥深くでデータからテキストへの変換を行うには、デフォルトのエンコーディングを変更するしかありません。
と
file.encoding はどうですか?
file.encoding システム プロパティを使用して、Java が I/O に使用するデフォルトの文字エンコーディングを設定することもできます。残念ながら、ファイル名が文字列にデコードされる方法には影響がないようです。
jnlp 内から locale を実行すると、必ず出力されます
LANG=
LC_COLLATE="C"
LC_CTYPE="C"
LC_MESSAGES="C"
LC_MONETARY="C"
LC_NUMERIC="C"
LC_TIME="C"
LC_ALL=
解決策を伴うスタックオーバーフローの最も類似した問題はこれです: encoding-issues-on-Java-7-file-names-in-os-x
しかし、解決策は、Javaプログラムの実行をスクリプトでラップすることです
#!/bin/bash
export LC_CTYPE="UTF-8" # Try other options if this doesn't work
exec java your.program.Here
しかし、ウェブスタートのためにこのオプションを利用できないと思います。また、プログラム内から LC_CTYPE 環境変数を設定する方法が見つかりませんでした。
解決策または回避策はありますか?
PS :
シェルからプログラムを直接実行すると、OSX 10+Java 7 でもファイル/ディレクトリが正しく書き込まれます。この問題は、JNLP+OSX+Java7 の組み合わせでのみ発生します。