CSVファイルを読み込む - 萌えJava超入門
テキストファイルを読み込む

CSVファイルを読み込む

テキストファイルの値を二次元の配列やListとして読み込みます。

萌えJava超入門
ここで扱うCSVファイルは
カンマで区切られただけの
単純なものだけだ。
すまんがよろしく頼む。

目次

1. CSVファイルとは


CSVファイルとは、「Comma Separated Value」の略です。
日本語にすると、「カンマで区切られた値」ってことですね。

以下の yuyuyu_ms932.csv をご覧ください。
,」カンマで区切って表の様なデータを表現しています。
CSVファイルの拡張子は「.csv」です。
萌えJava超入門 萌えJava超入門
このCSVファイルのサンプルは
Excel対策として敢えて
文字コードを MS932 にしている。
お名前 ,おなまえ  ,勇者服,刻印,特記事項
結城 友奈,ゆうき ゆうな,桃色,桜 ,知的に見える伊達メガネ
東郷 美森,とうごう みもり,,朝顔,国防仮面
犬吠埼 風,いぬぼうざき ふう,黄色,オキザリス,女子力斬り
犬吠埼 樹,いぬぼうざき いつき,,鳴子百合,Deathの正位置
三好 夏凜,みよし かりん,,サツキ,にぼっしー

「yuyuyu_ms932.csv」は、値に「"」ダブルクォーテーションや「,」カンマ、改行が含まれない単純なCSVファイルです。
ダウンロードして、ワークスペース(例では wsディレクトリ)に保存してください。

上手くダウンロード出来なかった方は
こちらもご参照ください。↓



2. CSVファイルを二次元配列にする

手順は以下のようになります。
  1. BufferedReaderで、行ごとにArrayList<String> list に保存します。
  2. list の要素を一つずつ String#.splitメソッドで配列にします。
  3. この配列を二次元配列 array2D にします。

それでは実際のコードを見てみましょう。
Sample05_01.java と、
ReadFile_01.java の
2つのクラスを作成しました。

上手く読み込めれば以下のように表示されると思います。

//ReadFile_01.java

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.UnsupportedEncodingException;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;

class ReadFile_01 {

  public static String[][] toStringArray2D(
              File inputFile,
              String encoding,
              String delimiters
  ){
      String[][] array2D = null;

      ArrayList<String> list = fileToList(inputFile, encoding);

      if(list!=null){
          array2D = new String[list.size()][];
          for(int i=0; i< list.size(); i++){
              array2D[i] = list.get(i).split(delimiters);
          }
      }else{
          return null;
      }
      return array2D;
  }

  private static ArrayList<String> fileToList(
              File inputFile,
              String encoding
  ){
      ArrayList<String> list = null; //try-catch の外で宣言。

      try {
          //ここは慣用句です。
          BufferedReader br = new BufferedReader(
                        new InputStreamReader(
                            new FileInputStream(inputFile), encoding
                        )
                    );

          //list に書き出します。
          list = new ArrayList<String>();
          String strLine;
          while((strLine = br.readLine()) != null) {
              list.add(strLine);
          }
          br.close();

      } catch (UnsupportedEncodingException e) {
          e.printStackTrace();
      } catch (FileNotFoundException e) {
          e.printStackTrace();
      } catch (IOException e){
          e.printStackTrace();
      }
      return list;
  }
}

ReadFile_01クラスの解説です。

fileToList は、前のページの Sample04_02 クラスをメソッドにしたものです。
引数に ファイルと、文字コードを与えると、
ファイルを読んで ArrayList(list)に返します。
fileToList は、privateなので、このクラス内でしか使用できません。

toStringArray2D は、引数に ファイルと、文字コードと、区切り文字 を与えると、
内部で fileToListメソッドを呼び出します。
戻り値 list の要素一つ一つを、String#.splitメソッドで配列にして、  結果を 二次元配列 (array2D))に返します。



Sample05_01クラスは、ReadFile_01.toStringArray2Dメソッドを実行して、
結果を表示します。

//Sample05_01.java

import java.io.File;

class Sample05_01{
  public static void main(String[] args){

    final String DELIMITERS = ",";//区切り文字
    String pathName = "yuyuyu_ms932.csv";
    File inputFile= new File(pathName);

    String[][] array2D
           = ReadFile_01.toStringArray2D(inputFile, "MS932", DELIMITERS);

    //表示
    if(array2D != null){
        for(int i=0; i<array2D.length; i++){
            System.out.printf("%02d\t", i);
            for(int j=0; j<array2D[i].length; j++){//←それぞれの行の要素数

                String str = array2D[i][j];
                //インデントを気にせず表示
                System.out.print(str + "\t");

                /*インデントを合わせて表示
                StringBuilder format = new StringBuilder();
                format.append("%");
                switch(j){
                    case 2:
                      format.append("-3");
                      break;
                    case 0:
                      format.append("-5");
                      break;
                    case 3:
                      format.append("-6");
                      break;
                    case 1:
                      format.append("-11");
                      break;
                    default:
                      break;
                }
                format.append("s\t");
                System.out.printf(format.toString(), str);
                */
            }
            System.out.println();//改行
        }
        System.out.println("end");
    }else{
        System.out.println("null");
    }
  }

}
読込がうまういかない場合は NullPointerException になります。

萌えJava超入門 萌えJava超入門
Sample05_01 は
落ち着いて見れば
ほとんど表示用なのね?
萌えJava超入門
表示の方が大変だったよ。
実践ならCSVにアウトプット
するだろうしな。

Sample05_01.java と、
ReadFile_01.java と、
yuyuyu_ms932.csv を
ws に保存して、
以下のコマンドを実行してみてください。

上手く読み込めれば以下のように表示されると思います。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Sample05_01.java
ws>java Sample05_01
00  お名前      おなまえ           勇者服  刻印        特記事項
01  結城 友奈   ゆうき ゆうな       桃色    桜         知的に見える伊達メガネ
02  東郷 美森   とうごう みもり     青      朝顔        国防仮面
03  犬吠埼 風   いぬぼうざき ふう   黄色    オキザリス  女子力斬り
04  犬吠埼 樹   いぬぼうざき いつき 緑      鳴子百合    Deathの正位置
05  三好 夏凜   みよし かりん       赤      サツキ      にぼっしー
end




3. CSVファイルにも文字コードがある

CSVファイルと言っても普通のテキストファイルですから文字コードがあります。
yuyuyu_ms932.csv は Excel での閲覧を考慮して、文字コードを MS932 にしましたが、
時代は既に UTF-8 が一般化していて、UTF-8 のCSVファイルを扱う機会も多いでしょう。
UTF-8 のCSVファイルを読み込む場合には、InputStreamReaderの第二引数で、UTF-8 を指定してください。

UTF-8のCSVファイルを読み込む
  BufferedReader br = new BufferedReader(
                new InputStreamReader(
                    new FileInputStream(pathName), "UTF-8"
                )
            );

萌えJava超入門
CSVファイルはExcelで開くことが多いが、
Excelは文字コードが MS932 というのが
ネックだ。
UTF-8 だと化けちゃう。(注)
萌えJava超入門 萌えJava超入門
わかる~!
今どき UTF-8 が文字化けって
ありえなくない?!
(注):BOM付きのUTF-8 なら化けません。
    ただ、Excelで上書き保存すると、文字コードが MS932 になってしまいます。
    ちょっとややこしいですね。


4. CSVファイルを二次元のListにする

今度は配列ではなく、ArrayListに取り込んでみましょう。
String#.splitメソッドで区切られた配列を、一行ずつArrayListに変換しています。
「合計や平均を一番右の列に付け加えたい」
みたいな場合には ArrayListの方が便利だったりしますね。

配列をArrayListに変換する (前出)
  String[] array;
  ArrayList<String> list
      = new ArrayList<String>(Arrays.asList(array));

萌えJava超入門
2次元配列をArrayListにする場合、
配列を一つずつ List化するぞ。
//Sample05_02.java

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;

class Sample05_02{
  public static void main(String[] args){

    final String DELIMITERS = ",";//区切り文字
    String pathName = "yuyuyu_ms932.csv";
    File inputFile= new File(pathName);

    String[][] array2D
           = ReadFile_01.toStringArray2D(inputFile, "MS932", DELIMITERS);

    ArrayList<ArrayList<String>> List2D = new ArrayList<ArrayList<String>>();

    for(int i=0; i< array2D.length; i++){
       //配列 を ArrayListに変換
       List2D.add(new ArrayList<String>(Arrays.asList(array2D[i])));
    }

    //表示
    if(List2D != null){
        for(int i=0; i<List2D.size(); i++){
            System.out.printf("%02d\t", i);
            for(int j=0; j<List2D.get(i).size(); j++){//←それぞれの行の要素数

                String str = List2D.get(i).get(j);
                //インデントを気にせず表示
                System.out.print(str + "\t");

                /*インデントを合わせて表示
                StringBuilder format = new StringBuilder();
                format.append("%");
                switch(j){
                    case 2:
                      format.append("-3");
                      break;
                    case 0:
                      format.append("-5");
                      break;
                    case 3:
                      format.append("-6");
                      break;
                    case 1:
                      format.append("-11");
                      break;
                    default:
                      break;
                }
                format.append("s\t");
                System.out.printf(format.toString(), str);
                */

            }
            System.out.println();//改行
        }
        System.out.println("end");
    }else{
        System.out.println("null");
    }
  }

}
Sample05_02.java と、
ReadFile_01.java と、
yuyuyu_ms932.csv を
ws に保存して、
以下のコマンドを実行してみてください。

コマンドライン
>cd ws
ws>javac -encoding UTF-8 Sample05_02.java
ws>java Sample05_02
00  お名前      おなまえ           勇者服  刻印        特記事項
01  結城 友奈   ゆうき ゆうな       桃色    桜         知的に見える伊達メガネ
02  東郷 美森   とうごう みもり     青      朝顔        国防仮面
03  犬吠埼 風   いぬぼうざき ふう   黄色    オキザリス  女子力斬り
04  犬吠埼 樹   いぬぼうざき いつき 緑      鳴子百合    Deathの正位置
05  三好 夏凜   みよし かりん       赤      サツキ      にぼっしー
end


結果は配列の時と変わりませんね。

萌えJava超入門 萌えJava超入門 萌えJava超入門


お疲れ様でした。




© 2019 awasekagami