Java java.nio.Files 使い方~古いけどニューIO(アイオー)でCSV読み書き~

Java Filesを使う

java.nio

が使用できるようになって久しいですが、改めてファイル読み込みの処理を行おうと思います。

## CSVファイルの読み込み
CSVファイルはカンマ区切りのデータを保存するのに使用されます。よくMySQLやPoestgreなどのDBでも「CSV出力」とか「CSV読み込み」などを行います。

身近な例として、政府の[統計調査結果](https://www.e-stat.go.jp/help/dbview-4-20)などをCSVでダウンロードできたりします。

## CSV読み込み実装
CSVファイルを開いて、その中身を1行ずつ読み込みます。単純に読み込んで、コンソール(標準出力)に出力するだけの処理です。

なので、下のようなテストケースを実装しました。

1. 実装するメソッドは``readCsv()``です。
2. ``readCsv()``はstatic目祖度です。
3. 「D:\csv\c01.csv」というファイルを読み込見ます。
4. ファイルは文字コードが「SJIS」だったので文字コードを「SJIS」に指定します。

<テストコード>
```java
@Test
public void testReadCsv() {

List<String[]> res = CsvUtils.readCsv("D:\\csv\\c01.csv", "SJIS");
res.forEach(arr -> {
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + ", ");
}
System.out.println();
});
}
```

Assertは入れていない状態です。これから仕様を決めようというところです。

次は、実装するメソッドです。
1. 引数はファイルパスと文字コードの文字列です。
2. データを格納するListインターフェースに実体クラスの``ArrayList``を代入します。
3. ファイルパスから、文字コードを指定して読み取ります。
4. 取得した1行のデータにあるかもしれない「ダブルクォーテーション(\")」を空文字に置き換えます。(削除します)
5. 取得したデータ1行分をカンマ(,)で分解し文字列の配列に変換します。
6. 1行分のデータ(配列)をListに設定して返却します。
<実装コード>
```java
/**
* CSVファイルを読み込みListで返却する。
*
* @param filePath 読み込むファイルのパス(完全パス)
* @param encordName UTF-0, SJISなどのエンコード名
* @return String配列のList
*/
public static List<String[]> readCsv(String filePath, String encordName) {
List<String[]> dataList = new ArrayList<>();
try {
BufferedReader buf = Files.newBufferedReader(Paths.get(filePath), Charset.forName(encordName));
String line = null;

while((line = buf.readLine()) != null) {
dataList.add(line.replaceAll("\" ", "").split(","));
}
} catch (IOException e) {
e.printStackTrace();
}
return dataList;
}
```

とりあえずは、読み込みの処理ができました。
しかし、開いたファイルを閉じる処理が実装されていないので、あとで``buf.close()``を追加実装しました。

## 書き込み処理
上の読み込み処理の後に、返却される``List<String[]>`を引数にして`exportPath``にファイルを出力する処理です。

1. まずは、リソース読み込み用の``try~catch``を使用してファイルを書き込みで開きます。
2. リストから文字列の配列を取り出し、書き込みます。
3. 書き込みじは文字コードを「SJIS」に設定します。
4. 1行書き込んだら、次の行なので``newLine()``で次の行に進みます。

<書き込みの処理>
```java
/**
* List<String[]>のデータをCSV出力する
* @param dataList String[]配列のリスト
* @param exportPath 出力するCSVファイルのパス
*/
public static void exportCsv(List<String[]> dataList, String exportPath) {
try (BufferedWriter writer = Files.newBufferedWriter(Paths.get(exportPath), Charset.forName("SJIS"));) {

StringBuilder build = new StringBuilder();
for (String[] data : dataList) {
build.setLength(0);
for (int i = 0; i < data.length; i++) {
if (i == data.length - 1) {
build.append(data[i]);
} else {
build.append(data[i] + ", ");
}
}
writer.write(build.toString());
writer.newLine();
}
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
```

以上で、読み込みと書き込みの処理ができました。

でわでわ。。。

投稿者:

takunoji

音響、イベント会場設営業界からIT業界へ転身。現在はJava屋としてサラリーマンをやっている。自称ガテン系プログラマー(笑) Javaプログラミングを布教したい、ラスパイとJavaの相性が良いことに気が付く。 Spring framework, Struts, Seaser, Hibernate, Playframework, JavaEE6, JavaEE7などの現場経験あり。 SQL, VBA, PL/SQL, コマンドプロント, Shellなどもやります。

コメントを残す