使用 Apache Commons CSV 解析文件相对简单。CSVFormat 类提供一些常用的 CSV 变体:
标准逗号分隔值格式,与 RFC4180 相同,但允许空行。等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') .setQuote('"') .setRecordSeparator("\r\n") .setIgnoreEmptyLines(true) .setAllowDuplicateHeaderNames(true);
Microsoft Excel CSV 格式(使用逗号作为值分隔符)。请注意,Excel 使用的实际值分隔符取决于区域设置,可能需要自定义此格式以适应您的区域设置。
例如,要在法语系统上解析或生成 CSV 文件,将使用以下格式:
CSVFormat fmt = CSVFormat.EXCEL.withDelimiter(';');
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') .setQuote('"') .setRecordSeparator("\r\n") .setIgnoreEmptyLines(false) .setAllowMissingColumnNames(true) .setAllowDuplicateHeaderNames(true);
UNLOAD TO file_name 操作使用的默认 Informix CSV UNLOAD 格式。这是逗号分隔的格式,使用 LF 字符作为行分隔符。值不用引号引起来,特殊字符用 ‘\’ 转义。默认空字符串为 “\\N”。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') .setEscape('\\') .setQuote("\"") .setRecordSeparator('\n');
UNLOAD TO file_name 操作使用的 Informix CSV UNLOAD 格式(转义被禁用)。这是逗号分隔的格式,使用 LF 字符作为行分隔符。值不用引号引起来,特殊字符用 ‘\’ 转义。默认空字符串为 “\\N”。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') .setQuote("\"") .setRecordSeparator('\n')
mongoexport 操作使用的 MongoDB CSV 格式(尚不支持解析)。
mongoexport 操作使用的 MongoDB TSV 格式(尚不支持解析)。
MySQL CSV 格式。SELECT INTO OUTFILE 和 LOAD DATA INFILE 操作使用的默认 MySQL 格式。这是一种制表符分隔格式,使用LF字符作为行分隔符。值不用引号引起来,特殊字符用 ‘\’ 转义。默认空字符串为 “\\N”。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter('\t') .setEscape('\\') .setIgnoreEmptyLines(false) .setQuote(null) .setRecordSeparator('\n') .setNullString("\\N") .setQuoteMode(QuoteMode.ALL_NON_NULL);
SQL*Loader 实用程序使用的默认 Oracle 格式。这是以逗号分隔的格式,以系统行分隔符作为记录分隔符。需要时,值用双引号引起来,特殊字符用 ‘"’ 转义。默认空字符串为 “”,值被修剪。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') // default is {@code FIELDS TERMINATED BY ','} .setEscape('\\') .setIgnoreEmptyLines(false) .setQuote('"') // default is {@code OPTIONALLY ENCLOSED BY '"'} .setNullString("\\N") .setTrim() .setSystemRecordSeparator() .setQuoteMode(QuoteMode.MINIMAL);
COPY 操作使用的默认 PostgreSQL CSV 格式。这是一种以 LF 字符作为行分隔符的逗号分隔格式。值是双引号,特殊字符用 ‘"’ 转义。默认的NULL字符串是 “”。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() setDelimiter(',') setEscape('"') setIgnoreEmptyLines(false) setQuote('"') setRecordSeparator('\n') setNullString("") setQuoteMode(QuoteMode.ALL_NON_NULL);
COPY 操作使用的默认 PostgreSQL 文本格式。这是一种以 LF 字符作为行分隔符的制表符分隔格式。值用双引号引起来,特殊字符用 “”” 转义。默认的 NULL 字符串是 “\\N”。
等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter('\t') .setEscape('\\') .setIgnoreEmptyLines(false) .setQuote('"') .setRecordSeparator('\n') .setNullString("\\N") .setQuoteMode(QuoteMode.ALL_NON_NULL);
RFC-4180 定义的 RFC-4180 格式。等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter(',') .setQuote('"') .setRecordSeparator("\r\n") .setIgnoreEmptyLines(false);
制表符分隔格式。等同于如下的 CSVFormat.Builder 设置:
CSVFormat.DEFAULT.builder() .setDelimiter('\t') .setQuote('"') .setRecordSeparator("\r\n") .setIgnoreSurroundingSpaces(true);
要解析 Excel CSV 文件,请编写:
Reader in = new FileReader("path/to/file.csv"); Iterable<CSVRecord> records = CSVFormat.EXCEL.parse(in); for (CSVRecord record : records) { String lastName = record.get("Last Name"); String firstName = record.get("First Name"); }
要处理以字节顺序标记(BOM)开头的文件(如某些Excel CSV文件),需要额外的步骤来处理这些可选字节。您可以使用 Apache Commons IO 中的 BOMInputStream 类,例如:
final URL url = ...; final Reader reader = new InputStreamReader(new BOMInputStream(url.openStream()), "UTF-8"); final CSVParser parser = new CSVParser(reader, CSVFormat.EXCEL.withHeader()); try { for (final CSVRecord record : parser) { final String string = record.get("SomeColumn"); ... } } finally { parser.close(); reader.close(); }
你可能会发现创建这样的东西很方便:
/** * Creates a reader capable of handling BOMs. */ public InputStreamReader newReader(final InputStream inputStream) { return new InputStreamReader(new BOMInputStream(inputStream), StandardCharsets.UTF_8); }