目次
Javaでの文字化けの原因と対処法
JavaでファイルやDBに格納されているデータを読み書きした際の文字化けの原因・対処方法についてまとめました。
Javaの文字コードは?
Java内部で文字はUTF-16で扱われます。
String型とchar型
String型
UTF-16で文字列を扱います。
char型
UTF-16を構成する16ビット単位で扱います。
注意が必要なのは、char = 1文字ではなく
UTF-16にはサロゲーペアがあり、その際はchar2つで1文字を表します。
入出力での文字コード変換
FileReader / FileWriter
FileReader
読み込み時に、ファイルで使用している文字コードをUTF-16に変換します。
FileWriter
書き込み時に、UTF-16からシステムのデフォルト文字コードに変換します。
FileReader / Writer は簡単にファイルの読み書きが行えますが、自動で文字コード変換するため、システム標準以外の文字があると文字化けします。
文字を扱う場合は、次に記載する明示的に文字コードを指定する方法をおすすめします。
InputStreamReader / InputStreamWriter
入出力時に使用する文字コードを明示的に指定できます。
文字化けが起きた時の対処法
FileReader・Writerを使用している場合
InputStreamReader/Writerを使用して明示的に文字コードを指定します。
InputStreamReader/Writerを使用している場合
UTF-16の文字コード表と、入出力で使用している文字コードの文字コード表が異なる可能性があります。
有名なのが、「波ダッシュ問題」です。
文字コードの変換表を作って対応します。
Javaでは、java.nio.charset で文字コード定義を独自に変換することができます。
もしくは、UTF-16に変換しないで、そのまま出力するという方法もあります。
例えば、InputStreamReader で読み込んだ文字列を、String型やchar型の変数に格納すると、その時点でUTF-16の文字コードに変換されます。
そのため、読み込んだ byteデータのまま、出力に使用する場合は、UTF-16への変換をはさみません。そのため、回避できる文字化けもあります。
※必ず文字化けしない保証はありません。UTF-16への変換をはさまないだけで、入力・出力に使用する文字コードで文字コード表が異なる場合は、文字化けします。
サロゲートペアの文字の場合
char型を使用している場合は、サロゲートペアの文字で文字化けを起こす可能性あります。
そのため、サロゲートペアの文字を適切に扱う場合は、java.text.BreakIteratorを使用すると、サロゲートペアも適切に1文字として扱うことができます。
入力・出力がすべてUnicodeの文字であれば、特に問題はありませんが、JISやSJISなど他の文字コードがある場合は、注意して扱う必要があります。
文字コード・・・奥が深いです(^^;