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();
}
}
```
以上で、読み込みと書き込みの処理ができました。
でわでわ。。。