

JAVAで、テキストファイルを読み込む処理を下記の様に作ったのですが、  
読み込むテキストファイルが、EUCやShift-JIS、GB2312などのように、  
UTF-8以外の場合、読み込んだStringの中が、文字化け状態です。

ユニコード（UTF-8)に変換して、読み込まれていないのが原因？

尚、読み込むファイルの文字コードの判定方法は不明なので、  
今は、下記の様に固定で、UTF-8を指定しています。

★事前に文字コードを判定する処理や、このソースへ追加／修正することで、  
JAVAが何かの変換処理で？サポートしている？文字コードなら、  
UTF-8として、Stringに、読み込めるようにできないでしょうか？

[code]

    InputStreamReader   fr  = null;
    BufferedReader      br  = null;
    
    try {
        fr  = new InputStreamReader(new FileInputStream(strFile_name), "UTF-8");
        br  = new BufferedReader(fr);
    
        // 既存のreadLine()では\rまたは\n、および\r\nにて改行とみなしている。
        String strLine  = null;
        int    iCount   = 0;
        while ((strLine = br.readLine()) != null) { // null=ファイルの最後
            file_text_line.add(strLine);
            iCount++;
        }
    
        br.close();
        fr.close();
    
        return iCount;  // 読込み成功（注意：0件の時もある）
    }
    catch (FileNotFoundException e) {
    
[/code]


CC BY-SA 3.0
2016-09-15T01:39:57.303
28892
2016-10-07T10:10:27.177
2016-10-07T00:57:05.430
754
17129
question
java
JAVAで、 utf8 以外のテキストファイルを読み込むと文字化けする


まず基本的にStringの内部表現はUTF-16固定です（JVMのオプションで変えれなくもない）。`InputStreamReader`の二つ目の引数はReaderで読み取ろうとしているバイト列のエンコーディングを指定するためで、ご質問の場合はテキストファイルのエンコーディングを指定する必要があります。  
残念ながらJava標準ライブラリには与えられたバイト列から自動でエンコーディングを判定してStringにしてくれる関数などはありませんので、手動できめるか、自分で判定用関数を書くか、何らかの外部ライブラリを使うしかありません。  
以下いくつかJava用ライブラリの例ですが、まず前提として何の追加情報もないバイト列からエンコーディングを100%当てる方法はないので（ウェブブラウザとかでも良く文字化けしますよね）外れた場合の対処手段は用意したほうが良いと思います。

  * [ICU4J](http://site.icu-project.org/)（つい最近までGoogle Chromeで使われてたやつ）
  * [juniversalchardet](https://code.google.com/archive/p/juniversalchardet/)（昔のFirefoxのアルゴリズムをJavaに移行したもの）
  * [jChardet](http://jchardet.sourceforge.net/)（同上）

正直精度はどれも微妙ですが、ICU4Jの例を以下に。

[code]

    //ファイルのバイトストリーム（一応バッファーに通す）
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(strFile_name));
    
    //ICU4JのCharsetDetectorクラスでエンコーディングを推測できる
    CharsetDetector cd = new CharsetDetector();
    cd.setText(bis);
    CharsetMatch cm = cd.detect();
    
    //cm.getConfidence()であってる確率を取得（0-100）
    //この値で判定を採用するかを決めるのもありだと思います
    //与えたバイト数が短いと基本低確率
    if(cm.getConfidence() > 70) {
        //７割以上の確立であってる
    } else {
        //７割以下であってる
    }
    
    //判定されたcharsetを取得
    String charset = cm.getName();
    //または直接Readerを取得
    Reader r = cm.getReader();
    
[/code]


CC BY-SA 3.0
2016-09-15T07:59:05.277
28902
2016-09-15T08:06:18.853
2016-09-15T08:06:18.853
3974
3974
28892
answer


昔の知識ですが、EUC-JPやShift_JIS系なら `"JISAutoDetect"` を指定する手があります。

Java8の時代にはもうないかも、と思ったけど[まだある](https://docs.oracle.com/javase/8/docs/technotes/guides/intl/encoding.doc.html)みたいです。


CC BY-SA 3.0
2016-10-07T10:10:27.177
29416
2016-10-07T10:10:27.177
17037
28892
answer