扩展库 / csv
csv
数据格式基于 XRT 的 UTF-8 CSV/TSV 读写。按行处理大文件,按表头读写字典,显式提交文件输出。
2026-10-30 冻结工具链:Windows/Linux 综合门禁分别执行 88/77 阶段,77/71 符合要求,仍真实退出 1。 八组基础 C、20 组首错组合、454 项 Python 互通、线程、19 个原型及新增流式双语 JIT/AOT 通过; 仍有 M5 嵌套数组、M3 私有构造器、M2 顶层 AOT 退役阻断,Windows 另有关闭态事务回滚 OOM 残留。 核心 AOT 当前已通过;下方旧日期的缺符号记录只属历史,不能替代本版发布签收。
内存表格
import csv
csv.Writer output = csv.create()
output.write(["name", "city"])
output.write(["Alice", "上海"])
Buffer data = output.finish()
csv.DictReader rows = csv.openDict(data)
while rows.next()
dict<string> row = rows.row()
println(row["name"] + "|" + row["city"])
end
rows.close()
输出 Alice|上海。open(string) 接受的是文件路径,不是 CSV 文本;文本使用 parse(text), 原始字节使用 open(Buffer)。全部字段为字符串,不自动猜测数字和日期。
函数与对象
| 函数 | 返回值与用途 |
|---|---|
open(Buffer|string path) | Reader;Buffer 输入保存快照,文件输入逐行读取。 |
parse(string text) | array<var>,每项是一行字符串数组;整份结果驻留内存。 |
create() / createFile(string path) | Writer;内存或事务文件输出。 |
stringify(array<array<string>> rows) | 完整 CSV 字符串。 |
openDict(Buffer|string path) | DictReader;首行为表头,重复名称或数据列数不符抛 CsvError。 |
createDict(headers, writeHeader=true) | DictWriter;headers 为 array<string>,决定列顺序。 |
createDictFile(path, headers, writeHeader=true) | 字典行文件写入器;缺失键写空串,多余键抛 CsvError。 |
Reader 提供 next()、field(index)、row()、close(),及 eof、rowNumber、count 属性。 行号和字段索引从 0 开始,没有当前行时 rowNumber/count 为 -1。field/row 返回独立结果。 DictReader 提供 next/row/close、eof/rowNumber 和表头副本 headers,第一条数据行编号为 1。
Writer/DictWriter 提供 write、close、finish、finishText。finish 取走 Buffer;finishText 直接接管底层缓冲并返回 string,避免再复制整份文本。两者仅限内存模式且只能二选一、取一次。 C 侧的 xcsv_writer_take_text 返回值由调用方使用 xrtFree 释放。最后一行没有换行时, next 可返回 true 而 eof 已为 true;遍历始终使用 while next()。
格式与限额
读选项顺序:delimiter、quote、strict、maxInput、maxOutput、maxField、maxRows、maxFields。 写选项顺序:delimiter、quote、newline、quoteAll、writeBOM,然后是相同的五项限额。 stringify 只接受前五项写格式选项,使用默认限额。可以按名字只传所需选项。
| 参数 | 默认值与约束 |
|---|---|
| delimiter / quote | 逗号 / 双引号;均为单个可打印 ASCII,分隔符另允许 TAB,两者不可相同。 |
| strict | true;false 只放宽引号语法,不允许非法 UTF-8 或 NUL。 |
| newline / quoteAll / writeBOM | "lf" / false / false;输出换行另可选 "crlf"。 |
| maxInput | 268435456;读原始输入字节,写字段 UTF-8 字节累计量。 |
| maxOutput | 536870912;读解码字段字节,写包含引号/分隔符/BOM/换行的总字节。 |
| maxField | 16777216;单字段 UTF-8 字节,不是字符数。 |
| maxRows / maxFields | 1000000 / 10000000;累计行数/字段数,包含表头。 |
import csv
csv.Writer output = csv.create(delimiter="\t", newline="crlf")
output.write(["甲", "a\tb", ""])
csv.Reader rows = csv.open(output.finish(), delimiter="\t")
assert rows.next()
assert rows.field(1) == "a\tb"
println(rows.count) // 3
rows.close()
读取支持 LF/CRLF/CR,保留引用字段内部的换行,只跳过开头的 UTF-8 BOM。 单个空字段与零字段空行不同。限额 0 取消该项上限,负数拒绝;这些配额不等于总内存或 CPU 限额。 parse(string) 在复制输入前按 UTF-8 字节数检查 maxInput;大输入应使用流式 open。 不支持多字节分隔符、编码猜测、反斜杠转义方言或 Excel 公式防护。
文件必须显式提交
createFile/createDictFile 使用目标同目录的临时文件,父目录必须已存在。 只有 close 成功才替换目标;未提交析构或失败时保留旧目标,并清理临时文件。 这不承诺断电持久性;文件系统故障可能使清理失败,远程文件系统的原子性不作保证。
发生错误不要继续提交原 Writer。内存结果使用 finish,文件使用 close;析构不是隐式提交。
错误与生命周期
参数非法为 ValueError,限额超出为 RangeError,字段索引越界为 IndexError, 格式/UTF-8/表头错误为 CsvError,关闭后使用等状态错误为 RuntimeError, 分配与读写故障分别为 MemoryError/IOError。错误保留底层原因和 CSV 数据位置。
底层 IO/内存首错已经存在时,补充 CSV 位置的诊断分配失败不会覆盖它:直接发布原始流错误, CSV 自身的错误码和位置仍由 C Reader/Writer Error() 查询。正常情况下包装错误包含完整 cause。
原始字节中 NUL 不合法,Buffer 输入按真实长度拒绝。语言层的文本、字段、表头、 路径及方言选项在进入 C 字符串接口前拒绝内嵌 NUL;任意二进制输入请使用 Buffer。 同一对象串行使用,不同对象可并发;自定义 IO 回调不得重入操作或销毁当前 CSV 对象。
C API
公共头为 extlibs/csv/include/xrt_csv.h,实现为 manifest 的四个 C 编译单元。 xrtCsvReaderCreate/OpenMemory/OpenFile、Next/EOF/Error、Close/Destroy 负责读取; xrtCsvWriterCreate/CreateMemory/OpenFile、Write、Close/TakeBuffer、Error/Destroy 负责写入。 方言必须通过 xrtCsvDialectInit 初始化;五项有效限额继承 XRT 默认值。 写入器有字段或累计输入配额时,超限字段只扫描至超过剩余配额的首字节; 达到配额边界的字段仍可写入。C 字段指针仍须指向有效的 NUL 结尾字符串。 深度、压缩倍率、资源标志及保留字段必须为零,显式设置会在 reader/writer 创建时拒绝。
C OpenMemory 借用内存,必须保持输入有效不变;行字段在下次 Next/Close/Destroy 后失效。 takeOwnership=true 在创建失败时也消费传入流。创建可能返回带错误的非 NULL 对象,需检查 Error()->iCode。 Next=false 需区分 EOF 与错误。内存 Writer 要先 Close 再 TakeBuffer,结果由调用者 xrtBufferDestroy。
C 外部输出流失败后不能回滚已写前缀。C 输入字符串以 NUL 结尾,不保留调用者字段; Destroy(NULL) 安全,文件 Destroy 不自动提交。
语言物理 ABI 头 csv_native.h 包含全部 19 个已实现入口,包括读取文本的 xcsv_reader_open_text; 门禁用真实生成的声明核对返回值、参数类型,并通过严格 GCC 的 missing-prototypes 检查防止漏声明。
双语范例
发行目录:xl run examples/extlibs/csv_basic.xl;xl run examples/extlibs/csv_files.xl。
C 对照位于 extlibs/csv/examples/basic.c 和 files.c,教学范例显式包含 CSV 核心源码,
可直接运行 xl run release/extlibs/csv/examples/basic.c 或
xl run release/extlibs/csv/examples/files.c;正式包仍分别编译四个 C 源。
两组固定输出覆盖表头、Unicode、TSV、严格错误、未提交保留旧文件和提交后读取汇总。基础范例还分别以 XLang stringify 和 C Writer 核对含逗号、引号与中文的完整 CSV 线格式。 C 与 XLang 文件范例都通过 XRT 排他创建临时目录,只操作其中的报表.csv,并在结束时清理;XLang 范例不再写入固定的 build/test 路径,不会覆盖工作目录中的同名文件。
2026-10-20:包内 XLang 文件事务测试也改用独占临时目录,单独运行及 Windows/Linux 包级门禁通过;完整 AOT 仍受主线缺符号阻断。
新增 extlibs/csv/examples/streaming.xl 与 streaming_c.c:逐行汇总、独立行快照、中文多行字段、 直接接管文本结果及超限失败状态。共享 streaming.expected.txt 六行输出;C 字段是借用,保留时显式复制, XLang row() 已返回独立结果。两份源码均可用 xl run 直接运行,不写文件。
验证与发布边界
Windows 专项包含七组 C 测试、143 个普通分配失败点与 47 个文件分配失败点、 四线程 1000 次往返、17 个实际生成 C 原型、XL JIT 与无输出核心 AOT、独立 C 与 TCC C 范例同输出。 Python 标准库 csv 双向互操作共 454 项,覆盖四种分隔符、两种引号、换行、BOM 及拒绝非法输入。 两份 C 教学范例的直接运行、GCC 编译与 XLang 范例已按同一固定输出对照。
2026-10-16 复跑:Linux 独立 C 的 ASan/UBSan/泄漏检查、454 项 Python 互操作,以及 Linux XLang 中央与包内用例、固定输出范例 JIT 均通过。默认语言门禁的无输出核心 AOT 在当前发布构建缺 xl6NativeHandleTraceLeaf;独立 Buffer 最小程序同样复现。旧构建核心 AOT 通过记录不代表当前产物已通过;test/check_xlang.sh --skip-aot 只用于明确验收 JIT,默认仍要求 AOT。Linux 全路径及 TSan 尚未验收。
当前页面是包能力与限定验证记录,不宣称完整 CLI/DLL、32 位/ARM 或长期负载已达到发布准入。
2026-10-17 Linux 包级门禁同次通过 C ASan/UBSan、Python 独立互操作 454 项、中央及包内 XLang JIT 用例、三份语言范例和两组 C/XLang 黄金输出逐字节对照。完整 AOT 的共享缺符号阻断不变。
当前发布版复验:七组独立 C 用例和 454 项 Python CSV 互通通过后,中央 XLang 用例在 array<array<string>>.append(array[...]) 报 TypeError;不导入 CSV 的最小文件也能复现。上述缺符号记录仅描述旧发布物,当前完整语言与 AOT 门禁仍需等主线嵌套数组写入修复后复跑,不能据历史通过记录签收本版。
门禁:tools/check_extlib_csv.ps1、tools/check_extlib_csv.sh、release/extlibs/csv/test/check_xlang.sh;每次源码或构建变更均应重新验证。
2026-10-30 专项增加 20 组底层首错与诊断 OOM 组合,分别覆盖读、读关闭、写、刷新、写关闭, 以及重复操作、析构和内存平衡。综合门禁现有八组 C 测试与三组双语范例;失败保留日志和原始退出码, 校验实际运行库及输入哈希,不把 M5 嵌套数组或 M3 私有构造器问题转成预期成功。当前结果以仓库发布验收矩阵为准, 不据新增 C 测试签收完整语言发布质量。
当前还确认 M2:顶层文档代码输出后 AOT 退出失败,局部 main 对照通过;保留原文和顶层生命周期正例。 Windows 的关闭态事务在改名失败后再遇路径分配 OOM,会留下临时文件,原目标不变。 file_rollback_closed.c 要求零残留,失败保留独占现场;此 RFS 问题需 XRT 的无分配关闭态回滚能力, 不在 CSV 另建一套系统路径实现,也不据 Linux 通过签收 Windows。