テキストファイルを読み込む
CSVファイルを読み込む
テキストファイルの値を二次元の配列やListとして読み込みます。
ここで扱うCSVファイルは
カンマで区切られただけの
単純なものだけだ。
すまんがよろしく頼む。
目次
1. CSVファイルとは
CSVファイルとは、「Comma Separated Value」の略です。
日本語にすると、「カンマで区切られた値」ってことですね。
以下の yuyuyu_ms932.csv をご覧ください。
「,」カンマで区切って表の様なデータを表現しています。
CSVファイルの拡張子は「.csv」です。
このCSVファイルのサンプルは
Excel対策として敢えて
文字コードを MS932 にしている。
お名前 ,おなまえ ,勇者服,刻印,特記事項
結城 友奈,ゆうき ゆうな,桃色,桜 ,知的に見える伊達メガネ
東郷 美森,とうごう みもり,青,朝顔,国防仮面
犬吠埼 風,いぬぼうざき ふう,黄色,オキザリス,女子力斬り
犬吠埼 樹,いぬぼうざき いつき,緑,鳴子百合,Deathの正位置
三好 夏凜,みよし かりん,赤,サツキ,にぼっしー
「yuyuyu_ms932.csv」は、値に「"」ダブルクォーテーションや「,」カンマ、改行が含まれない単純なCSVファイルです。
ダウンロードして、ワークスペース(例では wsディレクトリ)に保存してください。
上手くダウンロード出来なかった方は
こちらもご参照ください。↓
2. CSVファイルを二次元配列にする
手順は以下のようになります。
- BufferedReaderで、行ごとにArrayList<String> list に保存します。
- list の要素を一つずつ String#.splitメソッドで配列にします。
- この配列を二次元配列 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 になります。
Sample05_01 は
落ち着いて見れば
ほとんど表示用なのね?
表示の方が大変だったよ。
実践なら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"
)
);
CSVファイルはExcelで開くことが多いが、
Excelは文字コードが MS932 というのが
ネックだ。
UTF-8 だと化けちゃう。(注)
わかる~!
今どき UTF-8 が文字化けって
ありえなくない?!
4. CSVファイルを二次元のListにする
今度は配列ではなく、ArrayListに取り込んでみましょう。
String#.splitメソッドで区切られた配列を、一行ずつArrayListに変換しています。
「合計や平均を一番右の列に付け加えたい」
みたいな場合には ArrayListの方が便利だったりしますね。
配列をArrayListに変換する (前出)
String[] array;
ArrayList<String> list
= new ArrayList<String>(Arrays.asList(array));
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
結果は配列の時と変わりませんね。
お疲れ様でした。