CSVファイルをJavaで読み込んで文字コードを変換

2015.12.14

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

CSVファイルのデータをSQLに取り込みたい!
といった場合に役立ちます。
今回は、SJIS(Shift-JIS)のデータをUTF-8に変換してからカンマ区切りで配列にして、最後に標準出力で確認します。

使用するCSVデータ

no,title,year
1,てすと,2011
2,テスト,2012
3,test,
4,TEST,2015

コード

public class TestClass {
 
    public static void main(String[] args) {
 
        try {
     
            File file = new File("/usr/local/test.csv");
            FileInputStream input = new FileInputStream(file);  
            InputStreamReader stream = new InputStreamReader(input,"SJIS");
            BufferedReader buffer = new BufferedReader(stream);
       
            String line;
            
            while ((line = buffer.readLine()) != null) {
 
                byte[] b = line.getBytes();
                line = new String(b, "UTF-8");
                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();
 
        }
         
    }
     
}

出力結果

行ごとに配列をわけ、その要素の0~2番目を表示しています。

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

解説

ファイルのパスを指定してオブジェクトを生成。

File file = new File("読み込みたいファイルのパス");

入力ストリームを生成。 ( FileNotFoundException が発生 )

FileInputStream input = new FileInputStream(file);

入力ストリームの読み込み。 ( UnsupportedEncodingException が発生 )
ここでCSVファイルの文字コードを設定しないと文字化けします。

InputStreamReader stream = new InputStreamReader(input,"読み込むファイルの文字コード");

バッファに取り込み。

BufferedReader buffer = new BufferedReader(stream);

readLine()でバッファの1行を取り出す作業を、読み込める行が無くなるまでwhile文で実行。
line = buffer.readline() でBufferedReaderが保持する一行を取出しているので、ループする毎に書き変わります。

while ((line = buffer.readLine()) != null) {

取出した1行の文字セットを変換して新たに文字列を生成。( String で UnsupportedEncodingException が発生 )

byte[] b = line.getBytes();
line = new String(b,"変換したい文字コード");

文字列をカンマ区切りで配列に分けて要素ごとに出力。
16行目、line.splitの第2引数に"-1"を指定しないと、" 3,test, " の行の配列は " 3,test " の2つになってしまい他の行と要素数が違うため、出力結果の様にはなりません。

String[] columns = line.split(",", -1);
 
for (int j = 0; j < columns.length; j++) {
    System.out.println(j + " : " + columns[j]);
}

開いたストリームとバッファを閉じて関連するシステム・リソースを解放します。 ( IOException が発生 )

input.close();
stream.close();
buffer.close();

まとめ

タイトルの課題を進めようとしたときにググったのですが、コードが古かったり、ピンポイントでまとまってなかったりしたので、自分がその時に欲しかった内容を記事にしました。
今後は、データベースに登録するまでを書く予定です。