Ubuntu 22.04 安装 Apache Commons CSV 指南
在 Ubuntu 22.04 上安装 Apache Commons CSV 1.14.1:JDK 17 与 Maven 部署、Maven 依赖与官方发行包手动安装两种方案、sha512 校验、编译运行验证、多版本管理与卸载,全程实测。
Ubuntu 22.04 安装 Apache Commons CSV 指南
目标:在 Ubuntu 22.04 服务器上从零搭建可使用 Apache Commons CSV 1.14.1 的 Java 开发环境,覆盖 JDK 17 与 Maven 安装、两种获取 jar 的方案、最小验证代码的编译运行、多版本管理与卸载。全部命令与回显已在 Ubuntu 22.04 / CentOS 8(JDK 17 + Maven)实测通过。
一、环境信息
本文所有操作在一台全新初始化的 Ubuntu 22.04 服务器上完成,安装前先确认系统版本与架构,保证后续命令与环境一致。
cat /etc/os-release | head -2
回显(输出节选,实测首行):
NAME="Ubuntu"
PRETTY_NAME="Ubuntu 22.04.5 LTS"
uname -m
回显:
x86_64
| 项目 | 内容 |
|---|---|
| 操作系统 | Ubuntu 22.04.5 LTS(jammy) |
| 架构 | x86_64 |
| JDK | OpenJDK 17.0.20.1(openjdk-17-jdk) |
| 构建工具 | Apache Maven 3.6.3 |
| 目标组件 | Apache Commons CSV 1.14.1 |
其中 JDK 与 Maven 是使用 Commons CSV 的前置条件:CSV 库本体是纯 Java jar 包,编译示例代码需要 javac,工程化构建推荐 Maven。
二、版本选型与依赖分析
选型前先确认两件事:用哪个版本的 Commons CSV,以及这个版本会连带引入哪些 jar。
2.1 版本选择
查询 Maven 中央仓库的版本元数据,确认当前最新稳定版:
curl -fsS https://repo1.maven.org/maven2/org/apache/commons/commons-csv/maven-metadata.xml | grep -oE '<latest>[^<]+</latest>|<release>[^<]+</release>'
回显:
<latest>1.14.1</latest>
<release>1.14.1</release>
curl -fsS https://repo1.maven.org/maven2/org/apache/commons/commons-csv/maven-metadata.xml | grep -oE '<version>[^<]+</version>' | tail -6
回显:
<version>1.10.0</version>
<version>1.11.0</version>
<version>1.12.0</version>
<version>1.13.0</version>
<version>1.14.0</version>
<version>1.14.1</version>
中央仓库最新与 release 均为 1.14.1,本文以此版本为准。官方发行包 RELEASE-NOTES.txt 中明确写着 "Commons CSV requires at least Java 8",即 1.14.1 最低要求 Java 8;本文统一使用 JDK 17(LTS)。版本选择参考:
| 版本 | Maven 坐标 | 最低 JDK | 说明 |
|---|---|---|---|
| 1.14.1 | org.apache.commons:commons-csv:1.14.1 | Java 8 | 当前 latest/release,本文实测版本 |
| 1.14.0 | org.apache.commons:commons-csv:1.14.0 | Java 8 | 上一个次版本,功能与 1.14.1 接近 |
| 1.13.0 | org.apache.commons:commons-csv:1.13.0 | Java 8 | 早期版本,历史项目兼容用 |
逐项说明:Maven 坐标在 pom.xml 依赖声明中原样引用;最低 JDK 一列,1.14.1 已用两条证据实测确认(RELEASE-NOTES.txt 原文与 class 文件版本号 major 52,即 Java 8 字节码),其余版本以中央仓库对应版本文档为准。
2.2 依赖分析:1.14.1 并非零依赖
很多旧资料称 Commons CSV 是"零依赖"库,这在 1.14.1 上已不成立。用 Maven 拉取后查看依赖树即可确认(工程创建见第四章):
cd /opt/csvlab/deptree && mvn dependency:tree
回显(输出节选,实测):
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ csv-deptree ---
[INFO] demo:csv-deptree:jar:1.0.0
[INFO] \- org.apache.commons:commons-csv:jar:1.14.1:compile
[INFO] +- commons-io:commons-io:jar:2.20.0:compile
[INFO] \- commons-codec:commons-codec:jar:1.19.0:compile
[INFO] BUILD SUCCESS
结论:commons-csv 1.14.1 在 compile 作用域带有两个传递依赖——commons-io 2.20.0 与 commons-codec 1.19.0。使用 Maven 时会自动下载,无感;但选择"手动下载 jar"方案(第五章方案B)时必须把这两个 jar 一起放进 classpath,否则运行期直接抛 NoClassDefFoundError(第五章有实测复现)。
2.3 CSV 解析库横向对比
💡 技术拓展:Java 生态里解析 CSV 的常见选择对比如下。
| 方案 | 依赖 | 方言支持 | 表头映射 | 适用场景 |
|---|---|---|---|---|
| JDK 手写 split(",") | 无 | 不识别引号内逗号/换行 | 手工实现 | 仅教学演示,字段含逗号即出错 |
| OpenCSV | opencsv + 若干依赖 | 较全(RFC 4180/MySQL 等) | CsvToBean 注解映射 | 需要注解绑定 JavaBean |
| Super CSV | super-csv 单包 | 较全 | CsvDozerBeanMapper 等 | 校验/POJO 映射,更新缓慢 |
| Jackson CSV (jackson-dataformat-csv) | 随 Jackson 体系 | 常见方言 | ObjectMapper 绑定 | 已用 Jackson 的 JSON 项目复用 |
| Commons CSV | 1.14.1 带 2 个 compile 依赖 | 12 个内置预设方言 | 枚举表头映射(Enum get) | 轻量、方言多、API 简洁 |
点名本文所用:Apache Commons CSV 1.14.1,理由是内置方言最全(Excel/MySQL/TDF/PostgreSQL/Oracle 等预设开箱即用)且 API 面小,学习和运维成本低。
三、安装 JDK 17 与 Maven
Ubuntu 22.04 官方仓库自带 openjdk-17-jdk 与 maven 包,直接用 apt 安装即可,无需添加第三方源。
3.1 更新软件源索引
apt-get update
回显(输出节选,实测尾部):
Hit:2 http://archive.ubuntu.com/ubuntu jammy InRelease
Hit:3 http://archive.ubuntu.com/ubuntu jammy-updates InRelease
Hit:4 http://archive.ubuntu.com/ubuntu jammy-backports InRelease
Reading package lists...
3.2 安装 JDK 17 与 Maven
apt-get install -y openjdk-17-jdk maven
回显(输出节选,实测尾部):
Setting up openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...
update-alternatives: using /usr/lib/jvm/java-17-openjdk-amd64/bin/jconsole to provide /usr/bin/jconsole (jconsole) in auto mode
Processing triggers for hicolor-icon-theme (0.17-2) ...
安装动作说明:openjdk-17-jdk 会带出 jdk-headless/jre/headless 等配套包,并用 alternatives 机制注册 /usr/bin/java、/usr/bin/javac 等命令;maven 包提供 /usr/bin/mvn。
3.3 验证安装
java -version
回显:
openjdk version "17.0.20.1" 2026-08-18
OpenJDK Runtime Environment (build 17.0.20.1+1-1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 17.0.20.1+1-1-22.04-Ubuntu, mixed mode, sharing)
javac -version
回显:
javac 17.0.20.1
mvn -version | head -3
回显:
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
再用 apt 记录安装版本号,作为后续运维基线:
apt-cache policy openjdk-17-jdk maven | grep -A1 'openjdk-17-jdk:\|maven:'
回显:
openjdk-17-jdk:
Installed: 17.0.20.1+1-1~22.04
--
maven:
Installed: 3.6.3-5
三项验证均指向 JDK 17 与 Maven 3.6.3,特别注意 mvn -version 中的 "Java version" 行必须也是 17,否则 Maven 会用旧 JDK 编译(见第九章 Q2)。
四、方案A:Maven 中央仓库依赖
这是推荐的工程化方案:在 pom.xml 声明依赖,由 Maven 自动解析 commons-csv 及其两个传递依赖。
4.1 创建工程与 pom.xml
mkdir -p /opt/csvlab/deptree/src/main/java/demo && cd /opt/csvlab/deptree
回显无输出(命令成功即为 0)。
cat > pom.xml <<'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>demo</groupId>
<artifactId>csv-deptree</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>17</maven.compiler.source>
<maven.compiler.target>17</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-csv</artifactId>
<version>1.14.1</version>
</dependency>
</dependencies>
</project>
EOF
回显无输出。pom 要点逐项说明:maven.compiler.source/target 声明用 JDK 17 语法编译;project.build.sourceEncoding 强制 UTF-8,避免含中文源码乱码;依赖块只声明 commons-csv,传递依赖由 Maven 自动带出。
4.2 编写示例类
cat > src/main/java/demo/CsvQuick.java <<'EOF'
package demo;
import org.apache.commons.csv.*;
import java.io.*;
public class CsvQuick {
public static void main(String[] args) throws IOException {
String data = "city,pop\nBeijing,2189\nShanghai,2487\n";
CSVFormat fmt = CSVFormat.DEFAULT.builder().setHeader().setSkipHeaderRecord(true).get();
try (CSVParser parser = CSVParser.parse(data, fmt)) {
for (CSVRecord r : parser) {
System.out.println(r.get("city") + " pop=" + r.get("pop"));
}
}
}
}
EOF
回显无输出。代码说明:把字符串当 CSV 解析,首行按表头跳过,随后按列名取值。
4.3 编译打包并查看依赖树
mvn -q package
回显(首次运行会打印大量 Downloading 日志,静默模式下无告警即成功,退出码 0)。
mvn dependency:tree
回显(输出节选,实测):
[INFO] --- maven-dependency-plugin:2.8:tree (default-cli) @ csv-deptree ---
[INFO] demo:csv-deptree:jar:1.0.0
[INFO] \- org.apache.commons:commons-csv:jar:1.14.1:compile
[INFO] +- commons-io:commons-io:jar:2.20.0:compile
[INFO] \- commons-codec:commons-codec:jar:1.19.0:compile
[INFO] BUILD SUCCESS
4.4 运行验证
java -cp 'target/classes:/root/.m2/repository/org/apache/commons/commons-csv/1.14.1/commons-csv-1.14.1.jar:/root/.m2/repository/commons-io/commons-io/2.20.0/commons-io-2.20.0.jar:/root/.m2/repository/commons-codec/commons-codec/1.19.0/commons-codec-1.19.0.jar' demo.CsvQuick
回显:
Beijing pop=2189
Shanghai pop=2487
运行验证通过,说明 Maven 方案下依赖已完整落盘到本地仓库 /root/.m2/repository/,可用 ls 复核:
ls /root/.m2/repository/org/apache/commons/commons-csv/1.14.1/
回显:
_remote.repositories
commons-csv-1.14.1.jar
commons-csv-1.14.1.jar.sha1
commons-csv-1.14.1.pom
commons-csv-1.14.1.pom.sha1
五、方案B:官方发行包手动安装
无 Maven 的服务器(或只想起一个最小环境)可用官方发行包:从 Apache 下载目录取二进制包,校验后解压,把 jar 放进 classpath 使用。
5.1 下载与 sha512 校验
mkdir -p /opt/csvlab && cd /opt/csvlab
curl -fsSLO https://downloads.apache.org/commons/csv/binaries/commons-csv-1.14.1-bin.tar.gz
curl -fsSLO https://downloads.apache.org/commons/csv/binaries/commons-csv-1.14.1-bin.tar.gz.sha512
回显无输出。校验:官方 sha512 文件内容是裸哈希(没有文件名),直接 sha512sum -c 会报格式错误,需要把文件名拼到哈希后面:
echo "$(cat commons-csv-1.14.1-bin.tar.gz.sha512) commons-csv-1.14.1-bin.tar.gz" | sha512sum -c -
回显:
commons-csv-1.14.1-bin.tar.gz: OK
查看哈希原文并留存备查:
cat commons-csv-1.14.1-bin.tar.gz.sha512
回显:
22d25127957b7694cf5fe76425818d4a37465bffd2f527b156857389b36ddfa071fe22cde068552de8732eb4956d7f484b023231bbf6803f3f8bbba59da5efdc
5.2 解压与目录结构
tar xzf commons-csv-1.14.1-bin.tar.gz && ls commons-csv-1.14.1/
回显:
apidocs commons-csv-1.14.1-sources.jar commons-csv-1.14.1.jar LICENSE.txt NOTICE.txt RELEASE-NOTES.txt
结构说明:commons-csv-1.14.1.jar 是运行主 jar;apidocs/ 是离线 javadoc;RELEASE-NOTES.txt 含版本说明(含 "Commons CSV requires at least Java 8" 原文)。注意发行包内没有依赖 jar 目录,这正是 5.3 要解决的问题。
5.3 补齐运行期依赖(关键步骤)
只挂主 jar 直接运行会失败,实测复现:
cd /opt/csvlab/quick && javac -cp /opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar CsvDemo.java && java -cp .:/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar CsvDemo
回显:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/commons/io/output/AppendableOutputStream
at CsvDemo.main(CsvDemo.java:7)
Caused by: java.lang.ClassNotFoundException: org.apache.commons.io.output.AppendableOutputStream
at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:641)
at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:188)
at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:525)
解法:把第二章确认的两个 compile 依赖 jar 一并下载:
mkdir -p /opt/csvlab/lib && cd /opt/csvlab/lib
curl -fsSLO https://repo1.maven.org/maven2/commons-io/commons-io/2.20.0/commons-io-2.20.0.jar
curl -fsSLO https://repo1.maven.org/maven2/commons-codec/commons-codec/1.19.0/commons-codec-1.19.0.jar
回显无输出。核对文件:
ls -l /opt/csvlab/lib/
回显:
-rw-r--r-- 1 root root 374716 commons-codec-1.19.0.jar
-rw-r--r-- 1 root root 563971 commons-io-2.20.0.jar
5.4 编译与运行验证
cd /opt/csvlab/quick && javac -cp '/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar:/opt/csvlab/lib/*' CsvDemo.java && java -cp '.:/opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar:/opt/csvlab/lib/commons-io-2.20.0.jar:/opt/csvlab/lib/commons-codec-1.19.0.jar' CsvDemo
回显:
Zhang, San | 28
Li Si | 31
说明:编译时 classpath 可以用 lib/* 通配符;java -cp 同样支持。示例中带引号的字段 "Zhang, San" 被正确解析为单列,验证了引号处理正确。
六、方案对比与选型建议
| 维度 | 方案A:Maven 依赖 | 方案B:官方发行包手动安装 |
|---|---|---|
| 依赖解析 | 自动(io/codec 自动带出) | 手动(漏带会在运行期报错) |
| 升级 | 改版本号重新构建 | 重新下载校验解压 |
| 离线环境 | 需私服或预拷贝本地仓库 | 天然友好(3 个 jar 拷贝即可) |
| 调试源码/文档 | 需额外 sources/javadoc 包 | 发行包自带 sources.jar 与 apidocs |
| 版本一致性 | 声明即所得 | 靠目录约定与脚本 |
| 适用团队 | 日常工程开发 | 内网机器、临时脚本、教学环境 |
选型建议:默认用方案A,让 Maven 管依赖与版本;只有目标机器无法访问中央仓库、或只是临时跑脚本时用方案B,且必须带上 commons-io 与 commons-codec 两个 jar。
七、多版本 JDK 管理
Commons CSV 1.14.1 字节码是 Java 8,可以在更高版本 JDK 上运行;同一台机器常并存多个 JDK,用 alternatives 切换默认版本。
7.1 查看与切换默认 java
apt-get install -y openjdk-11-jdk-headless
回显(输出节选,实测尾部):
Setting up openjdk-11-jdk-headless:amd64 (11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu) ...
安装第二个 JDK 后查看 alternatives 注册表:
update-alternatives --list java
回显:
/usr/lib/jvm/java-11-openjdk-amd64/bin/java
/usr/lib/jvm/java-17-openjdk-amd64/bin/java
切换到 11 并验证,再切回 17:
update-alternatives --set java /usr/lib/jvm/java-11-openjdk-amd64/bin/java && java -version
回显:
update-alternatives: using /usr/lib/jvm/java-11-openjdk-amd64/bin/java to provide /usr/bin/java (java) in manual mode
openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu, mixed mode, sharing)
update-alternatives --set java /usr/lib/jvm/java-17-openjdk-amd64/bin/java && java -version | head -1
回显:
update-alternatives: using /usr/lib/jvm/java-17-openjdk-amd64/bin/java to provide /usr/bin/java (java) in manual mode
openjdk version "17.0.20.1" 2026-08-18
7.2 javac 与 Maven 的 JDK 指定
java 与 javac 是两个独立的 alternatives 组,切换 java 不影响 javac,需分别设置:
update-alternatives --set javac /usr/lib/jvm/java-17-openjdk-amd64/bin/javac
回显(已处于该目标时无输出,切换时打印 using 行)。
Maven 的 JDK 取自 JAVA_HOME 环境变量(未设置时回落系统默认),需要会话级指定时:
export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 && mvn -version | head -3
回显:
Apache Maven 3.6.3
Maven home: /usr/share/maven
Java version: 17.0.20.1, vendor: Ubuntu, runtime: /usr/lib/jvm/java-17-openjdk-amd64
工程级兼容老 JDK 的做法是在 pom 的 properties 里固定 maven.compiler.source/maven.compiler.target(第四章 pom 已示范),让字节码版本与运行时解耦。
7.3 多版本 jar 共存
不同 Commons CSV 版本可并存于独立目录,按需引用:
mkdir -p /opt/csvlib/1.14.1 && cp /opt/csvlab/commons-csv-1.14.1/commons-csv-1.14.1.jar /opt/csvlib/1.14.1/ && ls -R /opt/csvlib/
回显:
/opt/csvlib/1.14.1:
commons-csv-1.14.1.jar
引用时把目录里的完整路径写进 -cp 即可,避免把多个版本的 commons-csv 同时放上 classpath(类名相同,先加载者生效,行为不可预期)。
八、卸载
按"依赖 → 手动目录 → 系统包"的顺序卸载,每步都有验证命令。
8.1 清理 Maven 本地仓库中的组件缓存
Maven 本地仓库按「groupId 目录/artifactId 目录/版本号」分层存放,卸载时连同 groupId 整个目录一并删除,避免只删 artifact 子目录后留下空目录干扰后续验证。
rm -rf /root/.m2/repository/org/apache/commons/commons-csv /root/.m2/repository/commons-io /root/.m2/repository/commons-codec && ls /root/.m2/repository/ | grep -c 'commons-csv\|commons-io\|commons-codec'
回显:
0
8.2 删除手动安装目录
rm -rf /opt/csvlab /opt/csvlib && ls /opt/ | grep -c csv
回显:
0
8.3 卸载系统包
apt-get purge -y openjdk-17-jdk openjdk-17-jdk-headless openjdk-17-jre openjdk-17-jre-headless maven && apt-get autoremove -y
回显(输出节选,实测):
Removing maven (3.6.3-5) ...
Removing openjdk-17-jdk:amd64 (17.0.20.1+1-1~22.04) ...
Removing openjdk-17-jdk-headless:amd64 (17.0.20.1+1-1~22.04) ...
Removing openjdk-17-jre:amd64 (17.0.20.1+1-1~22.04) ...
Removing openjdk-17-jre-headless:amd64 (17.0.20.1+1-1~22.04) ...
Purging configuration files for maven (3.6.3-5) ...
本机因还装有 JDK 11,卸载后 /usr/bin/java 自动回落到 11,验证:
java -version
回显:
openjdk version "11.0.32.1" 2026-08-18
OpenJDK Runtime Environment (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu)
OpenJDK 64-Bit Server VM (build 11.0.32.1+1-post-1ubuntu1-22.04-Ubuntu, mixed mode, sharing)
若机器上没有其他 JDK,卸载后执行 java -version 会提示 /usr/bin/java: No such file or directory,即卸载干净。确认残留计数:
dpkg -l | grep -E 'openjdk-17|maven ' | wc -l
回显:
0
九、常见问题(FAQ)
Q1: 编译通过但运行抛 NoClassDefFoundError: org/apache/commons/io/output/AppendableOutputStream 怎么办?
这是 Commons CSV 1.14.1 的典型坑:它带 commons-io 2.20.0 与 commons-codec 1.19.0 两个 compile 传递依赖(见 2.2 节实测依赖树),手动方案漏带任一 jar 都会在首次使用 CSVParser 时报此错。把两个依赖 jar 加入 -cp 即可,完整命令见 5.4 节。
Q2: java -version 是 17,但 Maven 编译报 invalid target release: 17 怎么办?
说明 Maven 进程用的不是 JDK 17。用 mvn -version 看 "Java version" 行;若显示旧版本,为当前会话执行 export JAVA_HOME=/usr/lib/jvm/java-17-openjdk-amd64 后重试。CentOS 8 上此问题尤其常见(Maven 3.5.4 默认绑 1.8),处理方式相同。
Q3: sha512sum -c commons-csv-1.14.1-bin.tar.gz.sha512 报 "no properly formatted SHA512 checksum lines found" 怎么办?
官方 sha512 文件只有裸哈希没有文件名,不符合 sha512sum -c 要求的 "哈希 + 两个空格 + 文件名" 格式。用 echo "$(cat commons-csv-1.14.1-bin.tar.gz.sha512) commons-csv-1.14.1-bin.tar.gz" | sha512sum -c - 拼接后校验(见 5.1 节实测)。
Q4: downloads.apache.org 上找不到旧版本安装包怎么办?
该目录只保留当前发布线;历史版本在 Apache 归档:https://archive.apache.org/dist/commons/csv/binaries/,下载后同样按 5.1 节方法校验。
Q5: 含中文注释的源码 javac 报 "error: unmappable character (0xE8) for encoding US-ASCII" 怎么办?
平台默认编码不是 UTF-8 所致。临时解法 javac -encoding UTF-8;工程化解法在 pom.properties 里设置 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>(第四章 pom 已含)。
十、参考链接
- Apache Commons CSV 官方主页:https://commons.apache.org/proper/commons-csv/
- Commons CSV 用户指南:https://commons.apache.org/proper/commons-csv/user-guide.html
- Commons CSV javadoc(1.14.1):https://commons.apache.org/proper/commons-csv/apidocs/index.html
- 官方二进制下载目录:https://downloads.apache.org/commons/csv/binaries/
- Maven 中央仓库 commons-csv 目录:https://repo1.maven.org/maven2/org/apache/commons/commons-csv/
- 版本变更历史:https://commons.apache.org/proper/commons-csv/changes.html
- RFC 4180(CSV 格式规范):https://datatracker.ietf.org/doc/html/rfc4180