
本文介绍使用 Java 高效、安全地逐行读取 CSV 文件内容,并将其全部加载到 ArrayList 中,同时避免常见异常(如 NullPointerException、NoSuchElementException),为后续按行解析(如用 StringTokenizer 统计交易类型)提供可靠数据基础。
本文介绍使用 java 高效、安全地逐行读取 csv 文件内容,并将其全部加载到 arraylist
在 Java 中,将 CSV 文件的每一行文本导入 ArrayList<String> 是处理结构化文本数据的基础操作。虽然原始代码尝试用 Scanner 配合 nextLine() 实现,但其异常处理逻辑存在缺陷:NullPointerException 并非 nextLine() 的标准抛出异常(更可能是 s 为 null 导致),且依赖 moreLines 标志手动控制循环,易出错、可读性差。
推荐采用 BufferedReader + try-with-resources 方式,它更高效(缓冲读取)、更健壮(自动资源关闭)、语义更清晰:
import java.io.*;
import java.util.*;
public static List<String> readCsvLines(String filePath) {
List<String> lines = new ArrayList<>();
try (BufferedReader reader = new BufferedReader(new FileReader(filePath))) {
String line;
while ((line = reader.readLine()) != null) {
// 可选:跳过空行或纯空白行
if (line.trim().isEmpty()) continue;
lines.add(line);
}
} catch (FileNotFoundException e) {
System.err.println("错误:CSV 文件未找到 — " + filePath);
throw new RuntimeException(e);
} catch (IOException e) {
System.err.println("错误:读取文件时发生 I/O 异常");
throw new RuntimeException(e);
}
return lines;
}调用该方法后,即可将结果传入你的 getTokens() 方法进行逐行解析:
Miller (mlr) 是一个命令行工具,用于查询、整形和重新格式化名称索引数据,如 CSV、TSV、JSON 和 JSON Lines。它将 awk、sed、cut、join 和 sort 的功能整合到一个专为结构化数据处理而构建的单一工具中。
public static void main(String[] args) {
List<String> csvLines = readCsvLines("visadata.csv");
System.out.println("共加载 " + csvLines.size() + " 行交易数据");
// 传入每行字符串,供 StringTokenizer 解析字段(如交易类型、金额等)
int numTransactions = 0, debitCount = 0, creditCount = 0;
for (String line : csvLines) {
numTransactions++;
// 示例:假设每行格式为 "1234567890123456,DEBIT,150.00"
StringTokenizer tokenizer = new StringTokenizer(line, ",");
if (tokenizer.countTokens() >= 2) {
String cardNum = tokenizer.nextToken().trim();
String transType = tokenizer.nextToken().trim().toUpperCase();
if ("DEBIT".equals(transType)) debitCount++;
else if ("CREDIT".equals(transType)) creditCount++;
}
}
System.out.println("总交易数:" + numTransactions);
System.out.println("借记交易:" + debitCount + " 笔,贷记交易:" + creditCount + " 笔");
}⚠️ 注意事项:
- 不要使用 Scanner.nextLine() 循环配合 NoSuchElementException 判断 EOF —— 这属于反模式;BufferedReader.readLine() 返回 null 是标准且明确的结束信号。
- StringTokenizer 已属遗留类(Java 14+ 标记为 deprecated),生产环境建议改用 String.split(",") 或 java.util.Scanner(针对单行)或 OpenCSV 等专业库处理复杂 CSV(含引号、换行、转义)。
- 若 CSV 含中文或特殊字符,请显式指定字符集:new InputStreamReader(new FileInputStream(filePath), StandardCharsets.UTF_8)。
通过上述方式,你不仅能获得干净、完整的行数据列表,还能为后续精准的业务解析(如区分 debit/credit)打下坚实基础。

















