2011-12-22 14 views
4

Javaでストリームからテキストを読み込むコードを書くときによくある間違いは、エンコーディングの指定を忘れることです。何も指定しなければ、Javaはプラットフォームのデフォルトのエンコーディングを使用し、最終的には問題を引き起こします(「しかし、それは私のコンピュータ上で動作します!」)。デフォルトのエンコーディングを使用するコードを見つけるために使用するエンコーディングはどれですか?

これらの問題を見つけるために、できるだけ多くのI/O操作を中断する珍しいデフォルトのエンコーディングを使用したいと思います。その考え方は、少なくともASCII以外の文字はすべて切り詰められるということです。

ほとんどのドキュメントでは、UTF-8エンコーディングが使用されています。 ISO-8859-1は、単に入力を保存するだけで動作するかもしれません(バイトと文字の間の1:1マッピングです)。どんなウムラウトも2つの/ツリーバイトシーケンスで読み込まれます。しかし私はもっとうまくいくかどうか疑問に思っています。

list of supported encodingsからどのエンコードを使用することをお勧めしますか?

+0

あなたのJVMにいくつかのものがある場合、EBCDICは楽しいです。 http://en.wikipedia.org/wiki/Extended_Binary_Coded_Decimal_Interchange_Code – Mat

+0

私はEBCDIC(JavaでCp037)を使用していますが、このエンコーディングを使用すると、EBCDICエンコードされた文字列を使用してプロセスを作成しようとするため、Mavenをもう実行できません。 - ) –

答えて

1

私は、16ビットまたは32ビットのUTFのいずれかが、あなたに多くの文字列を壊すはずの "ヌル"文字を与えると思います。また、BOM(バイトオーダーマーカー)を持つものを使用すると、ファイルをさらに「分割する」必要があります。

しかし、私は、文字列、読者、および作成者がコード化されていないことを確認できるコード解析ツールがあると思います。

編集: FindBugsのは、これを行うことができるように見える:Dm: Reliance on default encoding (DM_DEFAULT_ENCODING)

2

UTF-16のデフォルトのエンコーディングは、UTF-16でないドキュメントを「マングリングする」可能性があります。

しかし、私はあなたが間違った方向に向かっていると思います。デフォルトのエンコーディングに依存する厄介なコードを検出するより良い方法は、PMDのようなカスタムルールを書くことです。 Stringの違法メソッドとコンストラクタを使用するコード、IOクラスなどを探してください。

(「奇妙なデフォルトのエンコーディングを使用」アプローチの問題は、あなたのテストが問題のあるコードのすべてを行使するのに十分ではないかもしれないということである、またはそれがコードを行使するが、マングリングを検出しない場合があります。)

+0

UTF-16はEBCDIC(Cp037)と同じ問題を抱えています:ProcessBuilderは突然プロセスを起動できません:-(これはデフォルトの文字セットを使用しているようです: -//しかしPMDのアプローチ+1。 –

1

java.nio.charset.CharsetDecoderを返すメソッドnewDecoder()を持っています。 Deconderには、あなたの仕事に役立つような方法isAutoDetecting()isChasetDetected()およびdetectedCharset()があります。残念ながら、これらのメソッドはすべてオプションです。

私は、利用可能なすべての文字セット(Charset.availableCharsets())を取り、それらが自動検出可能かどうかを確認する必要があると思います。したがって、新しいストリームを取得するときは、これらのオプション操作を実装する文字セットに対して、組み込みの自動検出メカニズムを使用してください。

これらのデコーダのどれもがチャセットを検出できない場合は、説明したようにストリームをデコードして他の文字セットを適用しようとする必要があります。プロセスを最適化するには、次の基準を使用して文字セットをソートします。

国別のアルファベットが最初に表示されます。たとえば、英字を扱う文字の前にキリル文字の文字セットを試してみてください。

国別アルファベットには、より多くの文字が含まれています。たとえば、日本語と中国語がキューの先頭に入ります。

この戦略の理由は、できるだけ早く失敗したいということです。テキストに日本語の文字が含まれていない場合は、ではなく、日本語であることをストリームの最初の文字で確認する必要があります。しかし、フランス語のテキストのデコードにASCII文字セットを使用しようとすると、最初にèが表示される前に、多くの文字を読み込む必要があります。

関連する問題