
Java で CSV ファイルをスマートに読み込む方法
CSV (Comma Separated Values) ファイルは、表形式のデータを扱うための一般的なファイル形式です。Java で CSV ファイルを読み込む方法はいくつかありますが、この記事では、基本的な方法からより洗練されたライブラリの利用まで、幅広く解説します。
1. BufferedReader を使った基本的な読み込み
最も基本的な方法は、java.io.BufferedReader を利用して1行ずつ読み込み、, (カンマ) で分割する方法です。
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class CSVReaderBasic {
public static void main(String[] args) {
String csvFilePath = "data.csv"; // 読み込む CSV ファイルのパス
try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) {
String line;
while ((line = br.readLine()) != null) {
// カンマで分割
String[] fields = line.split(",");
System.out.println(Arrays.toString(fields));
// ここで分割されたフィールドを処理する
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ポイント:
BufferedReaderを使うことで、効率的にファイルを1行ずつ読み込めます。line.split(",")で、1行の文字列をカンマで区切って String 型の配列に変換します。- try-with-resources 構文を使うことで、
BufferedReaderのクローズ処理を自動化できます。
注意点:
- この方法は、CSV ファイルの構造が非常に単純な場合に適しています。
- フィールド内にカンマが含まれる場合や、ダブルクォートで囲まれたフィールドを正しく処理できません。
2. Apache Commons CSV ライブラリの利用
より複雑な CSV ファイルを扱う場合や、より柔軟な読み込み処理を行いたい場合は、Apache Commons CSV ライブラリの利用を強く推奨します。このライブラリは、RFC 4180 に準拠した CSV ファイルの読み書きをサポートしており、様々なオプションを提供しています。
2.1. 依存関係の追加
Maven を利用している場合は、pom.xml に以下の依存関係を追加します。
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv<<artifactId>
<version>1.10.0</version> </dependency>
Gradle を利用している場合は、build.gradle に以下を追加します。
implementation 'org.apache.commons:commons-csv:1.10.0' // 最新バージョンを確認してください
2.2. Apache Commons CSV を使った読み込み
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class CSVReaderCommons {
public static void main(String[] args) {
String csvFilePath = "data.csv";
try (Reader reader = new FileReader(csvFilePath)) {
Iterable records = CSVFormat.DEFAULT.parse(reader);
for (CSVRecord record : records) {
// インデックスまたはヘッダー名でフィールドにアクセス
String field1 = record.get(0);
String field2 = record.get("ヘッダー2"); // ヘッダー行がある場合
System.out.println("フィールド1: " + field1 + ", フィールド2: " + field2);
// レコードのすべてのフィールドを処理する場合
// for (String field : record) {
// System.out.println("フィールド: " + field);
// }
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
ポイント:
CSVFormat.DEFAULT.parse(reader)で、CSV ファイルの内容をIterable<CSVRecord>として取得します。CSVRecordオブジェクトは、1行のデータを表します。record.get(index)でインデックスを指定してフィールドにアクセスできます(0から始まる)。- ヘッダー行がある場合は、
CSVFormat.DEFAULT.withHeader().parse(reader)を使用し、record.get("ヘッダー名")でヘッダー名を指定してフィールドにアクセスできます。
2.3. CSVFormat のカスタマイズ
CSVFormat をカスタマイズすることで、区切り文字、囲み文字、エスケープ文字、ヘッダーの有無などを細かく設定できます。
import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVRecord;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
public class CSVReaderCommonsCustom {
public static void main(String[] args) {
String csvFilePath = "custom_data.csv"; // 区切り文字がセミコロンのファイル
try (Reader reader = new FileReader(csvFilePath)) {
Iterable records = CSVFormat.newFormat(';').withHeader().parse(reader);
for (CSVRecord record : records) {
String field1 = record.get("名前");
String field2 = record.get("年齢");
System.out.println("名前: " + field1 + ", 年齢: " + field2);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
主なカスタマイズオプション:
.newFormat(char delimiter): 区切り文字を指定します。.withQuote(char quote): 囲み文字を指定します(デフォルトは")。.withEscape(char escape): エスケープ文字を指定します。.withHeader(String... header): ヘッダー行を指定します。.withFirstRecordAsHeader(): 最初の行をヘッダーとして扱います。.withSkipHeaderRecord(): ヘッダー行をスキップしてデータ行から読み込みを開始します。
3. OpenCSV ライブラリの利用
Apache Commons CSV と並んでよく利用されるのが、OpenCSV ライブラリです。こちらも柔軟な CSV ファイルの読み書きをサポートしています。
3.1. 依存関係の追加
Maven を利用している場合は、pom.xml に以下の依存関係を追加します。
<dependency>
<groupId>com.opencsv</groupId>
<artifactId>opencsv</artifactId>
<version>5.9</version></dependency>
Gradle を利用している場合は、build.gradle に以下を追加します。
implementation 'com.opencsv:opencsv:5.9' // 最新バージョンを確認してください
3.2. OpenCSV を使った読み込み
import com.opencsv.CSVReader;
import com.opencsv.CSVReaderBuilder;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
public class CSVReaderOpenCSV {
public static void main(String[] args) {
String csvFilePath = "data.csv";
try (CSVReader reader = new CSVReaderBuilder(new FileReader(csvFilePath)).build()) {
String[] nextRecord;
while ((nextRecord = reader.readNext()) != null) {
System.out.println(Arrays.toString(nextRecord));
// ここで読み込んだレコードを処理する
}
} catch (IOException | CsvException e) {
e.printStackTrace();
}
}
}
ポイント:
CSVReaderBuilderを使ってCSVReaderオブジェクトを生成します。reader.readNext()で、CSV ファイルの次の行を String 型の配列として読み込みます。- try-with-resources 構文は
CSVReaderでも利用可能です。
3.3. ヘッダー付き CSV の読み込み
ヘッダー付きの CSV ファイルを読み込む場合は、CSVReaderHeaderAware を利用できます。
import com.opencsv.CSVReaderHeaderAware;
import com.opencsv.exceptions.CsvException;
import java.io.FileReader;
import java.io.IOException;
import java.util.Map;
public class CSVReaderOpenCSVHeader {
public static void main(String[] args) {
String csvFilePath = "header_data.csv";
try (CSVReaderHeaderAware reader = new CSVReaderHeaderAware(new FileReader(csvFilePath))) {
Map nextRecord;
while ((nextRecord = reader.readMap()) != null) {
String name = nextRecord.get("名前");
String age = nextRecord.get("年齢");
System.out.println("名前: " + name + ", 年齢: " + age);
}
} catch (IOException | CsvException e) {
e.printStackTrace();
}
}
}
ポイント:
CSVReaderHeaderAwareを使うと、各行のデータがヘッダー名をキーとするMapとして読み込まれます。
まとめ
Java で CSV ファイルを読み込む基本的な方法から、Apache Commons CSV や OpenCSV といった便利なライブラリの利用方法まで解説しました。
- 単純な CSV ファイルの場合は、
BufferedReaderとsplit()で十分対応できることがあります。 - より複雑な CSV ファイルや、柔軟な読み込み処理が必要な場合は、Apache Commons CSV や OpenCSV のような専用のライブラリを利用することで、より堅牢で効率的なコードを書くことができます。
プロジェクトの要件や CSV ファイルの構造に合わせて、最適な方法を選択してください。これらの知識を活用して、Java での CSV ファイル処理をよりスマートに進めていきましょう。