Commons CSV 文件解析

CSV
使用 Apache Commons CSV 解析文件相对简单,CSVFormat 类提供一些常用的 CSV 变体。

使用 Apache Commons CSV 解析文件相对简单。CSVFormat 类提供一些常用的 CSV 变体:

DEFAULT

标准逗号分隔值格式,与 RFC4180 相同,但允许空行。等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    .setDelimiter(',')
    .setQuote('"')
    .setRecordSeparator("\r\n")
    .setIgnoreEmptyLines(true)
    .setAllowDuplicateHeaderNames(true);

EXCEL

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);

INFORMIX_UNLOAD1.3

UNLOAD TO file_name 操作使用的默认 Informix CSV UNLOAD 格式。这是逗号分隔的格式,使用 LF 字符作为行分隔符。值不用引号引起来,特殊字符用 ‘\’ 转义。默认空字符串为 “\\N”。

等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    .setDelimiter(',')
    .setEscape('\\')
    .setQuote("\"")
    .setRecordSeparator('\n');

INFORMIX_UNLOAD_CSV1.3

UNLOAD TO file_name 操作使用的 Informix CSV UNLOAD 格式(转义被禁用)。这是逗号分隔的格式,使用 LF 字符作为行分隔符。值不用引号引起来,特殊字符用 ‘\’ 转义。默认空字符串为 “\\N”。

等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    .setDelimiter(',')
    .setQuote("\"")
    .setRecordSeparator('\n')

MONGO_CSV1.7

mongoexport 操作使用的 MongoDB CSV 格式(尚不支持解析)。

MONGO_TSV1.7

mongoexport 操作使用的 MongoDB TSV 格式(尚不支持解析)。

MYSQL

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);

ORACLE1.6

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);

POSTGRESSQL_CSV1.5

COPY 操作使用的默认 PostgreSQL CSV 格式。这是一种以 LF 字符作为行分隔符的逗号分隔格式。值是双引号,特殊字符用 ‘"’ 转义。默认的NULL字符串是 “”。

等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    setDelimiter(',')
    setEscape('"')
    setIgnoreEmptyLines(false)
    setQuote('"')
    setRecordSeparator('\n')
    setNullString("")
    setQuoteMode(QuoteMode.ALL_NON_NULL);

POSTGRESSQL_TEXT1.5

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 定义的 RFC-4180 格式。等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    .setDelimiter(',')
    .setQuote('"')
    .setRecordSeparator("\r\n")
    .setIgnoreEmptyLines(false);

TDF

制表符分隔格式。等同于如下的 CSVFormat.Builder 设置:

CSVFormat.DEFAULT.builder()
    .setDelimiter('\t')
    .setQuote('"')
    .setRecordSeparator("\r\n")
    .setIgnoreSurroundingSpaces(true);

示例

解析 Excel CSV 文件

要解析 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);
}
如果在胜利前却步,往往只会拥抱失败;如果在困难时坚持,常常会获得新的成功。
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
公众号