将CSV文件读入数组

2025/04/06

1. 概述

简而言之,CSV(逗号分隔值)文件包含由逗号分隔符分隔的组织信息。

在本教程中,我们将研究将CSV文件读入数组的不同方法。

2. java.io中的BufferedReader

首先,让我们使用BufferedReader中的readLine()逐行读取记录,然后根据逗号分隔符将每行拆分为标记:

List<List<String>> records = new ArrayList<>();
try (BufferedReader br = new BufferedReader(new FileReader("book.csv"))) {
    String line;
    while ((line = br.readLine()) != null) {
        String[] values = line.split(COMMA_DELIMITER);
        records.add(Arrays.asList(values));
    }
}

请注意,更复杂的CSV(例如,引用或包括逗号作为值)将不会按预期使用此方法进行解析

3. java.util中的Scanner

接下来,让我们使用java.util.Scanner遍历文件内容并逐行检索:

List<List<String>> records = new ArrayList<>();
try (Scanner scanner = new Scanner(new File("book.csv"));) {
    while (scanner.hasNextLine()) {
        records.add(getRecordFromLine(scanner.nextLine()));
    }
}

然后我们将解析这些行并将其存储到一个数组中:

private List<String> getRecordFromLine(String line) {
    List<String> values = new ArrayList<String>();
    try (Scanner rowScanner = new Scanner(line)) {
        rowScanner.useDelimiter(COMMA_DELIMITER);
        while (rowScanner.hasNext()) {
            values.add(rowScanner.next());
        }
    }
    return values;
}

与以前一样,使用此方法无法按预期解析更复杂的CSV

4. OpenCSV

我们可以使用OpenCSV处理更复杂的CSV文件。

OpenCSV是一个第三方库,它提供了一个API来处理CSV文件

我们将使用CSVReader中的readNext()方法来读取文件中的记录:

List<List<String>> records = new ArrayList<List<String>>();
try (CSVReader csvReader = new CSVReader(new FileReader("book.csv"));) {
    String[] values = null;
    while ((values = csvReader.readNext()) != null) {
        records.add(Arrays.asList(values));
    }
}

要深入了解有关OpenCSV的更多信息,请查看我们的OpenCSV教程

5. 使用Files实用程序类

或者,我们可以使用Files类来实现相同的目的。此实用程序类由几个对文件和目录进行操作的静态方法组成。那么,让我们看看如何在实践中使用它。

5.1 使用Files#lines

lines()方法是Java 8中引入的增强功能之一,它允许我们将给定文件的所有行读取为Stream。那么,让我们看看它的实际效果:

try (Stream<String> lines = Files.lines(Paths.get(CSV_FILE))) {
    List<List<String>> records = lines.map(line -> Arrays.asList(line.split(COMMA_DELIMITER)))
        .collect(Collectors.toList());
}

这里,Paths.get(CSV_FILE)方法返回一个Path实例,该实例表示CSV文件的路径。此外,我们使用map()方法将CSV文件的每一行转换为字符串列表。请注意,我们使用try-with-resources来确保文件在最后自动关闭。

5.2 使用Files#readAllLines

类似地,Files提供了readAllLines()方法作为实现相同结果的另一种选择。此方法与lines()一样,接收Path对象作为参数,并直接返回包含指定CSV文件每一行的列表:

List<List<String>> records = Files.readAllLines(Paths.get(CSV_FILE))
    .stream()
    .map(line -> Arrays.asList(line.split(COMMA_DELIMITER)))
    .collect(Collectors.toList());

值得注意的是,我们使用Stream API将CSV文件读入List<List<String>>。这里需要注意的一点是readAllLines()会将所有内容一次性放入内存中,因此不要使用它来读取大文件

5.3 使用Files#newBufferedReader

另一个选择是使用newBufferedReader()方法,它返回BufferedReader的一个实例,从而提供一种更高效地读取文件的方法

接下来我们通过一个例子来学习如何使用该方法:

try (BufferedReader reader = Files.newBufferedReader(Paths.get(CSV_FILE))) {
    List<List<String>> records = reader.lines()
        .map(line -> Arrays.asList(line.split(COMMA_DELIMITER)))
        .collect(Collectors.toList());
}

如上所示,我们使用与之前相同的逻辑来读取CSV文件。请注意,与其他方法相比,newBufferedReader()是处理大文件的最佳方法

6. 总结

在这篇简短的文章中,我们探讨了将CSV文件读入数组的不同方法。

Show Disqus Comments

Post Directory

扫码关注公众号:Taketoday
发送 290992
即可立即永久解锁本站全部文章