Java解析CSV的关键在于文本结构是否简单、语义是否明确;StringTokenizer不支持正则、引号和空字段,仅适用于极简无引号无空字段的内部日志;split()需用负limit保留空字段;含引号或复杂结构必须用OpenCSV或Apache Commons CSV等专用库。

别用 StringTokenizer 解析真实 CSV
StringTokenizer 是 Java 1.0 的遗留类,它不支持正则、不识别引号、不保留空字段——而这三点恰恰是 CSV 的核心规则:
- 遇到
"a,,b",它返回["a", "b"](中间空字段直接消失) - 遇到
"field, with comma","value",它在逗号处硬切,拆成["field", " with comma", "value"](完全破坏字段完整性) - 分隔符是双字符(如
||)或需跳过转义("a"b")时,它完全无能为力
它唯一合理场景:你完全控制输入源,且格式极简,比如 "name age city" 这类纯空格分隔、绝无空字段、无嵌套的内部日志行。
用 split() 处理简单 CSV(无引号、有空字段)
对格式干净、不含引号但需保留空字段的 CSV 行(如 TSV 或旧系统导出),split() 是轻量可靠的选择,重点在两个参数:
- 分隔符写法要准确:逗号直接写
",";竖线写"\|";点号写"\.";制表符写"\t" - 必须传 负数 limit(如
-1):line.split(",", -1)才会保留所有空字段,包括开头、中间和结尾的""
示例:"a,,b,".split(",", -1) → ["a", "", "b", ""](4 个元素),而 .split(",") 只返回 ["a", "", "b"](丢掉末尾空串)。
立即学习“Java免费学习笔记(深入)”;
含引号或复杂结构?必须换专用解析器
只要出现以下任一情况,split() 和 StringTokenizer 都应立即弃用:
- 字段用双引号包裹(
"Smith, John","NYC") - 字段内含换行符、制表符或转义引号(
"line1 line2","a"b") - 分隔符本身出现在引号内(如
"a,b",c中的逗号不是分隔符)
此时应使用成熟 CSV 库:
- OpenCSV:轻量、API 简洁,自动处理引号、空字段、跨行字段
- Apache Commons CSV:更严格遵循 RFC 4180,适合金融/政务等高一致性要求场景
- 配置类文本可用
Properties.load();日志类建议用Pattern.compile()提取命名组
读取文件时先按行载入,再逐行解析
无论后续用哪种解析方式,读取 CSV 文件都应统一用 BufferedReader + try-with-resources:
- 避免
Scanner.nextLine()因空行或末尾换行符行为不稳定导致漏读 - 每行原始字符串完整进内存后,再交给解析逻辑,职责分离清晰
- 若需 trim 首尾空白,放在读取阶段做(
line.trim()),不影响后续分割语义


















