JavaでCSVファイルを読み込む基本は「BufferedReader で1行ずつ読み、split(",") でカンマ分割」です。シンプルなCSVならこれで十分ですが、引用符付きのフィールドや末尾の空欄では split(",") が正しく動きません。この記事では基本と、その限界・対処を解説します。
この記事の結論:単純なCSVは
BufferedReader + split(",", -1) で読めます(-1 で末尾の空欄も保持)。日本語はStandardCharsets.UTF_8 を明示。引用符内のカンマや改行を含む本格CSVは、自前のsplitではなくOpenCSVなどのライブラリを使います。基本:BufferedReaderとsplitで読み込む
UTF-8を明示して1行ずつ読み、カンマで分割します。split(",", -1) のように第2引数に -1 を渡すのが重要です(理由は後述)。
CSVを読み込む(UTF-8・末尾空欄保持)
import java.io.*;
import java.nio.charset.StandardCharsets;
public class Main {
public static void main(String[] args) {
String csvFile = "data.csv";
try (BufferedReader br = new BufferedReader(
new InputStreamReader(
new FileInputStream(csvFile), StandardCharsets.UTF_8))) {
String line;
boolean isHeader = true;
while ((line = br.readLine()) != null) {
if (isHeader) { isHeader = false; continue; } // ヘッダ行をスキップ
String[] cols = line.split(",", -1); // -1 で末尾の空欄も保持
System.out.println("名前=" + cols[0] + " 年齢=" + cols[1]);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意1:split(“,”) は末尾の空欄を捨てる
意外な落とし穴です。split(",")(第2引数なし)は末尾の空フィールドを削除します。CSVで末尾の列が空のとき、列数が合わなくなり ArrayIndexOutOfBoundsException の原因になります。
末尾の空欄の扱い
String line = "a,b,,";
String[] a = line.split(","); // ["a", "b"](末尾の空欄2つが消える)
System.out.println(a.length); // 2
String[] b = line.split(",", -1); // ["a", "b", "", ""](保持される)
System.out.println(b.length); // 4
CSVの分割では必ず
split(",", -1) を使いましょう。空の列が末尾にあると、split(",") では列数が減り、後続の cols[3] のようなアクセスで例外になります。注意2:引用符付きフィールドはsplitで壊れる
CSVの仕様(RFC 4180)では、フィールドをダブルクオートで囲み、その中にカンマや改行を含められます。このようなCSVを split(",") で分割すると、引用符内のカンマでも区切られてしまいデータが壊れます。
splitでは正しく分割できない例
// "Tokyo, Japan" のようにフィールド内にカンマがある
String line = "1,\"Tokyo, Japan\",100";
String[] cols = line.split(",", -1);
// 期待: [1, "Tokyo, Japan", 100](3列)
// 実際: [1, "Tokyo, Japan", 100](引用符内のカンマで4列に割れて壊れる)
System.out.println(cols.length); // 4(意図とずれる)
引用符・カンマ・改行を含む本格的なCSVは、自前のsplitではなくライブラリを使いましょう。代表的なのは OpenCSV や Apache Commons CSV です。引用符の処理やエスケープを正しく扱ってくれます。社内データなど「カンマや改行を含まない」と保証できる単純なCSVに限り、splitで十分です。
ライブラリ(OpenCSV)を使う場合
OpenCSVを使うと、引用符付きフィールドも正しく1行ずつ配列で取得できます(Mavenなどで依存を追加して使用します)。
OpenCSVでの読み込み(イメージ)
import com.opencsv.CSVReader;
import java.io.*;
import java.nio.charset.StandardCharsets;
try (CSVReader reader = new CSVReader(
new InputStreamReader(new FileInputStream("data.csv"), StandardCharsets.UTF_8))) {
String[] cols;
while ((cols = reader.readNext()) != null) {
// 引用符内のカンマも正しく1フィールドとして扱われる
System.out.println(String.join(" / ", cols));
}
}
よくある質問(FAQ)
Qsplit(“,”)で末尾の列が消えます。
A
split(",") は末尾の空フィールドを削除する仕様だからです。split(",", -1) と第2引数に -1 を渡すと、末尾の空欄も保持されます。Qフィールド内にカンマがあるCSVが正しく読めません。
A
split(",") は引用符を解釈しないため、"Tokyo, Japan" のような引用符内のカンマでも区切ってしまい壊れます。OpenCSVやApache Commons CSVなどのライブラリを使ってください。Q日本語のCSVが文字化けします。
AFileReaderが既定の文字コードで読むためです。
InputStreamReader で StandardCharsets.UTF_8 を明示してください(Excel由来のCSVはShift_JISのこともあるので、その場合は "MS932" など)。Qヘッダ行を飛ばすには?
A最初の1行を読み飛ばすフラグを使うか、
readLine() を先に1回呼んでから本処理に入ります。本文のように isHeader フラグで continue する方法が簡単です。まとめ
JavaでCSVを読み込むポイントを整理します。
- 単純なCSVは
BufferedReader+split(",", -1)(末尾空欄を保持) - 日本語は
StandardCharsets.UTF_8を明示(Excel由来はShift_JISも) - 引用符内のカンマ・改行を含むCSVはsplitでは壊れる → OpenCSV等のライブラリ
- ヘッダ行はフラグや先読みでスキップ
関連として、ファイルを読み込む方法・ファイルに書き込む方法・文字列をカンマ区切りで結合する方法もあわせて読むと、JavaのファイルI/O・CSV処理に強くなれます。

