跳转至

如何在 Java 中读取 CSV 文件

简介

CSV(Comma-Separated Values)文件是一种常见的文本文件格式,以逗号分隔值,常用于数据存储和交换。在 Java 开发中,读取 CSV 文件是一项常见任务,无论是处理数据报表、导入数据到数据库,还是进行数据分析等场景都可能会用到。本文将详细介绍在 Java 中读取 CSV 文件的相关知识,包括基础概念、使用方法、常见实践以及最佳实践。

目录

  1. CSV 文件基础概念
  2. 使用 Java 内置类库读取 CSV 文件
  3. 使用 OpenCSV 库读取 CSV 文件
  4. 使用 Apache Commons CSV 库读取 CSV 文件
  5. 常见实践
  6. 最佳实践
  7. 小结
  8. 参考资料

CSV 文件基础概念

CSV 文件本质上是纯文本文件,每一行代表一条记录,字段之间用逗号(也可以是其他分隔符,如制表符等)分隔。例如,一个简单的包含用户信息的 CSV 文件可能如下所示:

姓名,年龄,邮箱
张三,25,[email protected]
李四,30,[email protected]

第一行通常是表头(header),用于描述每列数据的含义。后续行则是实际的数据记录。

使用 Java 内置类库读取 CSV 文件

Java 本身没有专门针对 CSV 文件读取的标准类库,但可以使用 java.io 包中的类来实现基本的读取功能。下面是一个简单的示例:

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CSVReaderExample {
    public static void main(String[] args) {
        String csvFilePath = "path/to/your/file.csv";
        try (BufferedReader br = new BufferedReader(new FileReader(csvFilePath))) {
            String line;
            while ((line = br.readLine()) != null) {
                String[] values = line.split(",");
                for (String value : values) {
                    System.out.print(value + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码说明

  1. 使用 BufferedReaderFileReader 来读取文件内容。
  2. 逐行读取文件内容,使用 split(",") 方法将每行数据按逗号分隔成字符串数组。
  3. 遍历字符串数组并打印每个字段。

这种方法简单直接,但对于复杂的 CSV 文件格式(如字段中包含逗号、引号等特殊字符)处理起来比较困难。

使用 OpenCSV 库读取 CSV 文件

OpenCSV 是一个专门用于处理 CSV 文件的 Java 库,提供了更便捷的 API。

引入依赖

如果使用 Maven,可以在 pom.xml 中添加如下依赖:

<dependency>
    <groupId>com.opencsv</groupId>
    <artifactId>opencsv</artifactId>
    <version>5.7.1</version>
</dependency>

示例代码

import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class OpenCSVExample {
    public static void main(String[] args) {
        String csvFilePath = "path/to/your/file.csv";
        try (CSVReader reader = new CSVReader(new FileReader(csvFilePath))) {
            List<String[]> lines = reader.readAll();
            for (String[] line : lines) {
                for (String value : line) {
                    System.out.print(value + "\t");
                }
                System.out.println();
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}

代码说明

  1. 创建 CSVReader 对象并传入 FileReader
  2. 使用 readAll() 方法读取所有行数据,返回一个包含字符串数组的列表,每个字符串数组代表一行数据。
  3. 遍历列表并打印每行的字段。

OpenCSV 库可以处理更复杂的 CSV 文件格式,并且提供了更多的功能,如自定义分隔符、处理引号等。

使用 Apache Commons CSV 库读取 CSV 文件

Apache Commons CSV 也是一个强大的 CSV 处理库。

引入依赖

pom.xml 中添加依赖:

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.9.0</version>
</dependency>

示例代码

import org.apache.commons.csv.CSVFormat;
import org.apache.commons.csv.CSVParser;
import org.apache.commons.csv.CSVRecord;

import java.io.FileReader;
import java.io.IOException;

public class ApacheCommonsCSVExample {
    public static void main(String[] args) {
        String csvFilePath = "path/to/your/file.csv";
        try (FileReader fileReader = new FileReader(csvFilePath);
             CSVParser csvParser = new CSVParser(fileReader, CSVFormat.DEFAULT)) {
            for (CSVRecord csvRecord : csvParser) {
                for (String value : csvRecord) {
                    System.out.print(value + "\t");
                }
                System.out.println();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码说明

  1. 创建 CSVParser 对象并传入 FileReaderCSVFormat.DEFAULT(默认格式)。
  2. 遍历 CSVParser 中的 CSVRecord,每个 CSVRecord 代表一行数据。
  3. CSVRecord 中获取每个字段并打印。

Apache Commons CSV 库提供了丰富的配置选项,可以满足各种不同的 CSV 文件格式需求。

常见实践

  1. 处理表头:在读取数据时,通常需要区分表头和实际数据。可以先读取第一行作为表头,然后从第二行开始处理实际数据。例如:
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class HeaderHandlingExample {
    public static void main(String[] args) {
        String csvFilePath = "path/to/your/file.csv";
        try (CSVReader reader = new CSVReader(new FileReader(csvFilePath))) {
            List<String[]> lines = reader.readAll();
            if (!lines.isEmpty()) {
                String[] headers = lines.get(0);
                for (int i = 1; i < lines.size(); i++) {
                    String[] data = lines.get(i);
                    for (int j = 0; j < headers.length; j++) {
                        System.out.println(headers[j] + ": " + data[j]);
                    }
                    System.out.println();
                }
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}
  1. 数据转换:根据实际需求,可能需要将读取到的字符串数据转换为其他数据类型,如 IntegerDouble 等。例如:
import com.opencsv.CSVReader;
import com.opencsv.exceptions.CsvException;

import java.io.FileReader;
import java.io.IOException;
import java.util.List;

public class DataConversionExample {
    public static void main(String[] args) {
        String csvFilePath = "path/to/your/file.csv";
        try (CSVReader reader = new CSVReader(new FileReader(csvFilePath))) {
            List<String[]> lines = reader.readAll();
            for (String[] line : lines) {
                if (line.length >= 2) {
                    try {
                        int age = Integer.parseInt(line[1]);
                        System.out.println("Name: " + line[0] + ", Age: " + age);
                    } catch (NumberFormatException e) {
                        System.out.println("Invalid age value: " + line[1]);
                    }
                }
            }
        } catch (IOException | CsvException e) {
            e.printStackTrace();
        }
    }
}

最佳实践

  1. 错误处理:在读取 CSV 文件时,要进行充分的错误处理,包括文件不存在、格式错误等情况。可以使用 try-catch 块捕获异常并进行适当的处理。
  2. 性能优化:对于大型 CSV 文件,要注意性能问题。可以考虑分批读取数据,而不是一次性读取所有数据。例如,使用 CSVParser 的迭代器方式逐行读取,而不是使用 readAll() 方法。
  3. 数据验证:在读取数据后,对数据进行验证,确保数据的准确性和完整性。例如,验证邮箱格式、日期格式等。

小结

本文介绍了在 Java 中读取 CSV 文件的多种方法,包括使用 Java 内置类库、OpenCSV 库和 Apache Commons CSV 库。同时,还探讨了常见实践和最佳实践,如处理表头、数据转换、错误处理和性能优化等。不同的方法适用于不同的场景,开发者可以根据具体需求选择合适的方式来读取 CSV 文件。

参考资料