34488


サクラエディタを使って文字コード「UTF-8」を指定して保存したＣＳＶファイルをJAVAでSJISに変換してファイルの中身をコンソールに表示したいのですが日本語の表示のところで文字化けが出ている形です。  
なぜでしょうか。どう修正すれば文字化けがなくコンソール表示できるのでしょうか。  
●ＣＳＶファイルの中身  
no,title,year  
1,てすと,2011  
2,テスト,2012  
3,test,  
4,TEST,2015  
●実行結果  
0 : no  
1 : title  
2 : year

0 : 1  
1 : 縺ｦ縺吶→  
2 : 2011

0 : 2  
1 : 繝�繧ｹ繝�  
2 : 2012

0 : 3  
1 : test  
2 :

0 : 4  
1 : TEST  
2 : 2015

[code]

    public class TestClass {
    
        public static void main(String[] args) {
            try {
    
                File file = new File("C:\\Users\\test\\Desktop\\CSVデータ_utf8.txt");
                FileInputStream input = new FileInputStream(file);
                InputStreamReader stream = new InputStreamReader(input,"UTF-8");
                BufferedReader buffer = new BufferedReader(stream);
    
                String line;
    
                while ((line = buffer.readLine()) != null) {
    
                    byte[] b = line.getBytes();
                    line = new String(b, "SJIS");
                    String[] columns = line.split(",",-1);
    
                    for (int j = 0; j < columns.length; j++) {
                        System.out.println(j + " : " + columns[j]);
                    }
    
                    System.out.println("");
    
                }
    
                input.close();
                stream.close();
                buffer.close();
    
            } catch (UnsupportedEncodingException | FileNotFoundException e) {
                e.printStackTrace();
    
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
[/code]


CC BY-SA 3.0
2017-05-06T10:06:34.290
34484
2017-05-06T13:22:24.157
17348
question
java
UTF-8のファイルをSJISに変換後で文字化け。


[Javaの文字コード変換の文字化けについて](https://ja.stackoverflow.com/questions/34483/java%e3%81%ae%e6%96%87%e5%ad%97%e3%82%b3%e3%83%bc%e3%83%89%e5%a4%89%e6%8f%9b%e3%81%ae%e6%96%87%e5%ad%97%e5%8c%96%e3%81%91%e3%81%ab%e3%81%a4%e3%81%84%e3%81%a6)
にも書かせてもらいましたが、  
`java.io.PrintStream#println`の挙動によるものと思います。(文字列をデフォルトエンコーディングで変換して出力しているため)

独自にSJISデータを出力するのであれば、`java.io.OutputStream#write`メソッドでバイト列を出力するとよいと思います。

[code]

        // コード例 (出力部分)
        for (int j = 0; j < colummns.length; j++) {
            System.out.write((j + " : " + column[j]).getBytes("ISO8859_1"));
            System.out.println("");
        }
    
[/code]

ちなみに、提示例なら読み込んだ文字列を単に`System.out.println`で出力すれば期待する結果になると思います。


CC BY-SA 3.0
2017-05-06T10:51:11.717
34486
2017-05-06T10:51:11.717
20098
34484
answer


基本的にはBLUEPIXYさんのコメント通りに2行のコードを削るだけなのですが、「windowsのコンソールの出‌​力はシフトＪＩＳなので」と言うのはちょっと違うので、その点を補足しておきます。

まずは、JavaのデフォルトエンコーディングがUTF-8となっているMac環境で、あなたのコードそのまま(ファイルパスだけはMac用に修正しました)を実行した結果です。

>
[code]

>     0 : no
>     1 : title
>     2 : year
>  
>     0 : 1
>     1 : 縺ｦ縺吶→
>     2 : 2011
>  
>     0 : 2
>     1 : 繝�繧ｹ繝�
>     2 : 2012
>  
>     0 : 3
>     1 : test
>     2 :
>  
>     0 : 4
>     1 : TEST
>     2 : 2015
>  
[/code]

どんな文字に化けるかまで含めて、結果が完全に同じことがわかるかと思います。

では、何が起こっているかを2行目の「1,てすと,2011」について示しておきます。

まず、`line = "1,てすと,2011"`となっている状態で、`byte[] b =
line.getBytes();`が実行されると、`b`の内容は以下のようなバイト列になります。(*1)

>
[code]

>     31 2C E3 81 A6 E3 81 99 E3 81 A8 2C 32 30 31 31
>      1  , <--て--> <--す--> <--と-->  ,  2  0  1  1
>  
[/code]

(ひらがなや漢字(*2)はUTF-8では3バイトになります。Macではコード引用しても全角文字が半角文字の倍にはならないので、環境によっては上下の行の対応が大きくずれて見えているかもしれません、ひらがなが3バイト、その他が1バイトで対応させながらみてください。)

次の行の`line = new String(b,
"SJIS");`では、そのバイト列を無理やりShift_JISとして解釈させようとしているので、次のような形になります。

>
[code]

>     31 2C E3 81 A6 E3 81 99 E3 81 A8 2C 32 30 31 31
>      1  , <縺 > ｦ  <縺 > <吶 > <→ >  ,  2  0  1  1
>  
[/code]

以下のバイト列(Shift_JISでは、漢字は2バイト、半角カタカナは1バイト)が「正しく」変換されているのがわかります。

E3 81: 縺  
A6: ｦ  
99 E3: 吶  
81 A8: →

[文字コード表 シフトJIS(Shift_JIS)](http://charset.7jp.net/sjis.html)  
(検索でたまたまトップに出ただけのサイトを掲載していますが、誤りはないと思います。)

* * *

と言うわけで、Javaが保持している文字列は正しくコンソールに表示されているようですので、

**_どう修正すれば文字化けがなくコンソール表示できるのでしょうか。_**

と言う質問に対する答えはBLUEPIXYさんのコメントやuser20098さんの回答の最後にもありますが、次の2行を削除してやれば良いと言うことになります。

[code]

                byte[] b = line.getBytes();
                line = new String(b, "SJIS");
    
[/code]

文字エンコーディングの詳細を丸暗記するのは不可能ですが、具体的にバイト列と文字列の間の変換とは何が起こっているのかを意識すれば、理解しやすくなるかと思います。「文字化け」の仕組みがよく理解できない場合だけでも、文字コード表とにらめっこしてみてください。

*1 結果がMacと全く同じなので、UTF-8のバイト列を出力しているはずです。  
*2 昔のJISコードにある漢字の場合3バイト、その後追加された漢字については4バイトの場合もあります。


CC BY-SA 3.0
2017-05-06T13:15:13.600
34488
2017-05-06T13:22:24.157
2017-05-06T13:22:24.157
13972
13972
34484
answer