CSV ファイルの読み取り

JavaJavaBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Java で CSV (Comma-Separated Values、カンマ区切り値) ファイルを読み取る方法を学びます。CSV は、スプレッドシートやデータベースのエクスポートなどの表形式のデータを保存するために使用される一般的なファイル形式です。CSV ファイルの各行はデータの行を表し、列はカンマで区切られています。

Java で CSV ファイルを読み取る 3 つの異なるアプローチを探ります。

  • java.io パッケージの BufferedReader クラスを使用する
  • java.util パッケージの Scanner クラスを使用する
  • CSV 処理に人気のあるサードパーティライブラリである OpenCSV ライブラリを使用する

この実験の終わりまでに、特定の要件に基づいて、Java アプリケーションで CSV ファイルを読み取る最適な方法を選択できるようになります。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL java(("Java")) -.-> java/DataStructuresGroup(["Data Structures"]) java(("Java")) -.-> java/ObjectOrientedandAdvancedConceptsGroup(["Object-Oriented and Advanced Concepts"]) java(("Java")) -.-> java/FileandIOManagementGroup(["File and I/O Management"]) java(("Java")) -.-> java/ConcurrentandNetworkProgrammingGroup(["Concurrent and Network Programming"]) java/DataStructuresGroup -.-> java/arrays("Arrays") java/ObjectOrientedandAdvancedConceptsGroup -.-> java/arraylist("ArrayList") java/FileandIOManagementGroup -.-> java/files("Files") java/FileandIOManagementGroup -.-> java/create_write_files("Create/Write Files") java/FileandIOManagementGroup -.-> java/read_files("Read Files") java/FileandIOManagementGroup -.-> java/io("IO") java/ConcurrentandNetworkProgrammingGroup -.-> java/working("Working") subgraph Lab Skills java/arrays -.-> lab-117982{{"CSV ファイルの読み取り"}} java/arraylist -.-> lab-117982{{"CSV ファイルの読み取り"}} java/files -.-> lab-117982{{"CSV ファイルの読み取り"}} java/create_write_files -.-> lab-117982{{"CSV ファイルの読み取り"}} java/read_files -.-> lab-117982{{"CSV ファイルの読み取り"}} java/io -.-> lab-117982{{"CSV ファイルの読み取り"}} java/working -.-> lab-117982{{"CSV ファイルの読み取り"}} end

サンプル CSV ファイルとプロジェクト構造の作成

CSV ファイルの読み取りを開始する前に、プロジェクトが適切に設定されていることを確認しましょう。このステップでは、CSV ファイルの構造を調べ、メインの Java クラスを作成します。

CSV ファイルの理解

CSV (Comma-Separated Values、カンマ区切り値) ファイルは、表形式のデータを平文で保存します。各行は 1 つの行を表し、列はカンマで区切られています。CSV ファイルは、そのシンプルさと、Excel、Google Sheets、データベースシステムなどの多くのアプリケーションとの互換性のため、データ交換に広く使用されています。

サンプル CSV ファイルの調査

実験環境にはすでに ~/project/sample.csv にサンプル CSV ファイルが含まれています。まずはその内容を見てみましょう。

cat ~/project/sample.csv

以下の出力が表示されるはずです。

name,age,city
John,25,New York
Alice,30,Los Angeles
Bob,28,Chicago
Eve,22,Boston

この CSV ファイルには、ヘッダー行を含めて 4 行のデータがあり、人の名前、年齢、都市に関する情報が含まれています。

Java クラスの作成

次に、この実験全体で使用する src ディレクトリに CSVReaderDemo.java という名前の新しい Java クラスを作成しましょう。

VSCode で、サイドバーのエクスプローラーアイコンをクリックし、~/project/src ディレクトリに移動し、その上で右クリックして「新しいファイル」を選択します。ファイル名を CSVReaderDemo.java とします。

以下の基本構造をファイルに追加します。

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("CSV Reader Demo");

        // 次のステップでここに CSV 読み取りコードを追加します
    }
}
Java ファイルの作成

Java クラスをコンパイルして実行し、すべてが正しく設定されていることを確認しましょう。

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

以下の出力が表示されるはずです。

CSV Reader Demo

素晴らしい!これでプロジェクト構造が準備できました。次のステップでは、CSV ファイルを読み取るためのさまざまな方法を実装します。

BufferedReader を使用した CSV ファイルの読み取り

このステップでは、java.io パッケージの BufferedReader クラスを使用して、CSV ファイルを読み取る最初のアプローチを実装します。これは、Java でテキストファイルを読み取る一般的で簡単な方法です。

BufferedReader の理解

BufferedReader は、文字入力ストリームからテキストを読み取るクラスで、文字をバッファリングすることで、文字、配列、および行の効率的な読み取りを提供します。バッファサイズを指定することも、デフォルトサイズを使用することもできます。

BufferedReader を使用した CSV 読み取りの実装

CSVReaderDemo.java ファイルを更新して、BufferedReader を使用して CSV ファイルを読み取りましょう。ファイルの内容全体を以下のコードに置き換えます。

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 CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using BufferedReader");

        // Path to our CSV file
        String csvFile = "sample.csv";

        // Lists to store our data
        List<List<String>> data = new ArrayList<>();

        // Try-with-resources to ensure the reader gets closed automatically
        try (BufferedReader br = new BufferedReader(new FileReader(csvFile))) {
            String line;

            // Read each line from the file
            while ((line = br.readLine()) != null) {
                // Split the line by comma and convert to a List
                String[] values = line.split(",");
                List<String> lineData = Arrays.asList(values);

                // Add the line data to our main list
                data.add(lineData);
            }

            // Print the data we read
            System.out.println("\nData read from CSV file:");
            for (int i = 0; i < data.size(); i++) {
                List<String> row = data.get(i);
                System.out.println("Row " + i + ": " + String.join(", ", row));
            }

        } catch (IOException e) {
            System.err.println("Error reading the CSV file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
Java ファイルの更新

更新したコードをコンパイルして実行しましょう。

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

以下のような出力が表示されるはずです。

Reading CSV using BufferedReader

Data read from CSV file:
Row 0: name, age, city
Row 1: John, 25, New York
Row 2: Alice, 30, Los Angeles
Row 3: Bob, 28, Chicago
Row 4: Eve, 22, Boston

コードの説明

  1. ファイル入出力操作とデータ構造に必要な Java クラスをインポートします。
  2. CSV ファイル (sample.csv) へのパスを定義します。
  3. CSV データを二次元リストとして格納する List<List<String>> を作成します。
  4. try-with-resources ブロックを使用して、BufferedReader を使用後に自動的に閉じます。
  5. br.readLine() でファイルの各行を読み取ります。
  6. 各行について、line.split(",") を使用してカンマで分割し、List に変換します。
  7. 各行をメインのデータリストに追加します。
  8. 最後に、データを正しく読み取ったことを確認するためにデータを出力します。

BufferedReader アプローチは、CSV ファイルを含むテキストファイルの読み取りに簡単で効率的です。ただし、引用符で囲まれたカンマや改行を含むフィールドなど、より複雑な CSV 形式を扱う際には制限があります。

次のステップでは、Scanner クラスを使用した別のアプローチを探ります。

Scanner を使用した CSV ファイルの読み取り

このステップでは、java.util パッケージの Scanner クラスを使用して、CSV ファイルを読み取る 2 つ目のアプローチを実装します。Scanner クラスは、様々なソースから書式付き入力を読み取る便利な方法を提供します。

Scanner の理解

Scanner クラスは、区切り文字パターンを使用して入力をトークンに分割します。デフォルトでは空白文字に一致します。その後、様々な next メソッドを使用して、結果のトークンをさまざまな型の値に変換することができます。

Scanner を使用した CSV 読み取りの実装

CSVReaderDemo.java ファイルを更新して、Scanner を使用して CSV ファイルを読み取りましょう。ファイルの内容全体を以下のコードに置き換えます。

import java.io.File;
import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using Scanner");

        // Path to our CSV file
        String csvFile = "sample.csv";

        // Lists to store our data
        List<List<String>> data = new ArrayList<>();

        try (Scanner scanner = new Scanner(new File(csvFile))) {
            // Read each line from the file
            while (scanner.hasNextLine()) {
                String line = scanner.nextLine();

                // Split the line by comma and convert to a List
                String[] values = line.split(",");
                List<String> lineData = Arrays.asList(values);

                // Add the line data to our main list
                data.add(lineData);
            }

            // Print the data we read
            System.out.println("\nData read from CSV file:");
            for (int i = 0; i < data.size(); i++) {
                List<String> row = data.get(i);
                System.out.println("Row " + i + ": " + String.join(", ", row));
            }

        } catch (FileNotFoundException e) {
            System.err.println("CSV file not found: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

更新したコードをコンパイルして実行しましょう。

cd ~/project
javac -d . src/CSVReaderDemo.java
java CSVReaderDemo

以下のような出力が表示されるはずです。

Reading CSV using Scanner

Data read from CSV file:
Row 0: name, age, city
Row 1: John, 25, New York
Row 2: Alice, 30, Los Angeles
Row 3: Bob, 28, Chicago
Row 4: Eve, 22, Boston

コードの説明

  1. ファイル操作、Scanner、およびデータ構造に必要な Java クラスをインポートします。
  2. CSV ファイル (sample.csv) へのパスを定義します。
  3. CSV データを二次元リストとして格納する List<List<String>> を作成します。
  4. try-with-resources ブロックを使用して、Scanner を使用後に自動的に閉じます。
  5. scanner.hasNextLine()true を返す限り、scanner.nextLine() でファイルの各行を読み取ります。
  6. 各行について、line.split(",") を使用してカンマで分割し、List に変換します。
  7. 各行をメインのデータリストに追加します。
  8. 最後に、データを正しく読み取ったことを確認するためにデータを出力します。

Scanner アプローチは BufferedReader アプローチに似ていますが、さまざまな型のデータを解析するための便利なメソッドを提供します。ただし、BufferedReader と同様に、複雑な CSV 形式を扱う際には制限があります。

次のステップでは、複雑な CSV 形式をより効果的に処理する OpenCSV ライブラリを使用した、より堅牢なアプローチを探ります。

OpenCSV ライブラリを使用した CSV ファイルの読み取り

このステップでは、OpenCSV ライブラリを使用して、CSV ファイルを読み取る 3 つ目のアプローチを実装します。OpenCSV はサードパーティのライブラリで、引用符で囲まれたカンマや改行を含むフィールドなどの複雑なシナリオを処理する、堅牢な CSV 解析機能を提供します。

OpenCSV の理解

OpenCSV は Java 用の CSV パーサーライブラリで、すべての基本的な CSV 形式のバリエーションをサポートします。前のアプローチとは異なり、OpenCSV は引用符で囲まれたカンマ、改行、およびその他の特殊文字を含むフィールドを適切に処理します。これらは単純なカンマ区切りでは分割できません。

OpenCSV のセットアップ

まず、OpenCSV ライブラリとその依存関係をダウンロードしましょう。

cd ~/project
mkdir -p lib
curl -L -o lib/opencsv-5.7.1.jar https://repo1.maven.org/maven2/com/opencsv/opencsv/5.7.1/opencsv-5.7.1.jar
curl -L -o lib/commons-lang3-3.12.0.jar https://repo1.maven.org/maven2/org/apache/commons/commons-lang3/3.12.0/commons-lang3-3.12.0.jar
curl -L -o lib/commons-text-1.10.0.jar https://repo1.maven.org/maven2/org/apache/commons/commons-text/1.10.0/commons-text-1.10.0.jar
curl -L -o lib/commons-beanutils-1.9.4.jar https://repo1.maven.org/maven2/commons-beanutils/commons-beanutils/1.9.4/commons-beanutils-1.9.4.jar
curl -L -o lib/commons-collections-3.2.2.jar https://repo1.maven.org/maven2/commons-collections/commons-collections/3.2.2/commons-collections-3.2.2.jar
curl -L -o lib/commons-logging-1.2.jar https://repo1.maven.org/maven2/commons-logging/commons-logging/1.2/commons-logging-1.2.jar

より複雑な CSV ファイルの作成

引用符で囲まれたカンマを含む、より複雑な CSV ファイルを作成しましょう。

echo 'name,description,price
"Laptop","High-performance laptop, with SSD",999.99
"Smartphone","Latest model, with dual camera",499.99
"Headphones","Noise-canceling, wireless",149.99' > ~/project/products.csv

OpenCSV を使用した CSV 読み取りの実装

では、CSVReaderDemo.java ファイルを更新して、OpenCSV を使用して CSV ファイルを読み取りましょう。ファイルの内容全体を以下のコードに置き換えます。

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvValidationException;
import java.io.FileReader;
import java.io.IOException;

public class CSVReaderDemo {
    public static void main(String[] args) {
        System.out.println("Reading CSV using OpenCSV");

        // Path to our CSV file with complex data
        String csvFile = "products.csv";

        try (CSVReader reader = new CSVReader(new FileReader(csvFile))) {
            // Read and print the header
            String[] header = reader.readNext();
            if (header != null) {
                System.out.println("\nHeader: " + String.join(", ", header));
            }

            // Read and print each line
            String[] nextLine;
            int rowNumber = 1;

            System.out.println("\nData read from CSV file:");
            while ((nextLine = reader.readNext()) != null) {
                System.out.println("Row " + rowNumber + ":");
                for (int i = 0; i < nextLine.length; i++) {
                    System.out.println("  " + header[i] + ": " + nextLine[i]);
                }
                rowNumber++;
                System.out.println();
            }

        } catch (IOException | CsvValidationException e) {
            System.err.println("Error reading the CSV file: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

更新したコードをコンパイルして実行しましょう。

cd ~/project
javac -cp ".:lib/*" -d . src/CSVReaderDemo.java
java -cp ".:lib/*" CSVReaderDemo

以下のような出力が表示されるはずです。

Reading CSV using OpenCSV

Header: name, description, price

Data read from CSV file:
Row 1:
  name: Laptop
  description: High-performance laptop, with SSD
  price: 999.99

Row 2:
  name: Smartphone
  description: Latest model, with dual camera
  price: 499.99

Row 3:
  name: Headphones
  description: Noise-canceling, wireless
  price: 149.99

コードの説明

  1. OpenCSV ライブラリと Java の入出力から必要なクラスをインポートします。
  2. CSV ファイル (products.csv) へのパスを定義します。
  3. CSV ファイルを読み取るための CSVReader オブジェクトを作成します。
  4. reader.readNext() でヘッダー行を読み取り、後で使用するために保存します。
  5. その後、ループ内で reader.readNext() を使用して、残りの各行を読み取ります。行がなくなるまで続けます。
  6. 各行について、対応するヘッダーとともに各フィールドを出力します。

OpenCSV ライブラリは複雑な CSV 形式を自動的に処理し、引用符で囲まれたカンマを含むフィールドを正しく解析します。このため、複雑なデータを含む実世界の CSV ファイルに最適です。

OpenCSV の利点

OpenCSV は基本的なアプローチに比べていくつかの利点を提供します。

  1. 引用符で囲まれたカンマ、改行、およびその他の特殊文字を含むフィールドを正しく処理します。
  2. ビーン (Java オブジェクト) への読み取りをサポートしています。
  3. カスタム区切り文字、引用符、エスケープ文字などの高度な機能をサポートしています。
  4. 大きな CSV ファイルを効率的に処理します。

ほとんどの実世界の CSV ファイルを扱うアプリケーションでは、OpenCSV のような専用のライブラリを使用することが推奨されます。

まとめ

この実験 (Lab) では、Java で CSV ファイルを読み取る 3 つの異なるアプローチを探りました。

  1. BufferedReader を使用する:標準の Java 入出力ライブラリを使用したシンプルなアプローチです。基本的な CSV ファイルには適していますが、複雑な CSV 形式を扱う際には制限があります。
  2. Scanner を使用する:標準の Java ユーティリティライブラリを使用した別のアプローチです。BufferedReader と同様に、シンプルな CSV ファイルに適していますが、複雑な CSV 形式のサポートが不足しています。
  3. OpenCSV を使用する:CSV 処理用に特別に設計されたサードパーティのライブラリを使用した堅牢なアプローチです。引用符で囲まれたカンマ、改行、およびその他の特殊文字を含む複雑な CSV 形式を処理します。

各アプローチにはそれぞれの強みと使用例があります。

  • BufferedReaderScanner は、外部依存関係を避けたい場合のシンプルな CSV ファイルに適した選択肢です。
  • OpenCSV は、潜在的に複雑な CSV ファイルを扱う実世界のアプリケーションに最適な選択肢です。

これらの異なるアプローチを理解することで、特定の要件と CSV データの複雑さに基づいて最適な方法を選択することができます。

CSV ファイルはデータ処理、データ交換、およびデータ統合のシナリオで広く使用されています。CSV ファイルを読み取り、処理する能力は、特にデータに焦点を当てたアプリケーションや他のシステムとの統合において、Java 開発者にとって貴重なスキルです。