一个支持csv文件的读写、解析的库
以下内容由 AI 翻译,如有问题请 点此提交 issue 反馈
![]()
一款用于操作 CSV 文件的工具,支持 CSV 文件的读写和解析,并且兼容中文。
特性
-
🚀 读取、解析及结构化 CSV 文件
-
🌍 将结构化的 CSV 记录导出为 CSV 文件
-
💪 提供对 CSV 文件格式的配置支持
-
🛠️ 支持中文处理
![]()
源码目录
.
├── doc
│ ├── assets
│ ├── cjcov
│ ├── feature_api.md
│ └── design.md
├── samples
│ ├── csv_perf
│ ├── read_csv_file
│ ├── set_csv_header
│ └── write_csv_file
├── src
│ ├── appendable.cj
│ ├── buffered_reader.cj
│ ├── char_reader.cj
│ ├── constants.cj
│ ├── csv_out_format.cj
│ ├── csv_parse_format.cj
│ ├── csv_parser.cj
│ ├── csv_printer.cj
│ ├── csv_reader.cj
│ ├── csv_record.cj
│ ├── helper.cj
│ ├── lexer.cj
│ └── token.cj
│ └── utf8_reader_stream.cj
└── test
├── HLT
├── LLT
└── UT
├── CHANGELOG.md
├── LICENSE
├── README.md
├── README.OpenSource
sample意为使用示例doc指的是库的设计文档、提案、库的使用文档以及LLT用例的覆盖报告src是库的源码目录test包含测试用例,涵盖了HLT用例、LLT用例和UT用例
接口说明
主要涵盖核心类及其成员函数的详细说明,具体请参见 API
![]()
提供了两种编译方式
-
使用脚本编译
- 下载并配置编译脚本
- 执行 ciTest build 命令
-
使用包管理器编译
- 本三方库依赖于stdx,请参照stdx文档设置
CANGJIE_STDX_PATH路径 - 执行 cjpm build 命令
- 本三方库依赖于stdx,请参照stdx文档设置
示例
以下是一个示例 test.csv 文件的内容:
id,name,age,remark
30020,biboo,28,middle school student
30021,张飞,45,三国演义男4号𥻗𪧘
#这是第3行的注释,里面有转义的tab键和引用符号
30022,关\t羽,48,著名的武财神αβγ
30023,刘备,50,"胳膊比较长,善于编草鞋"
以下为示例代码:
import std.fs.*
import std.collection.*
import std.posix.*
import csv4cj.*
import stdx.encoding.json.*
main() {
let path: String = getcwd()
println("自定义输出:")
customPrintingDemo("${path}/test.csv")
println("\nJson输出:")
serialPrintingDemo("${path}/test.csv")
println("\nCSV自定义格式输出:")
csvPrint()
}
//自定义输出格式
func customPrintingDemo(fileName: String) {
//创建文件流
let fileStream = File(fileName, OpenMode.Read)
if (fileStream.canRead()) {
//创建字符读取的解析流
let stream = UTF8ReaderStream(fileStream)
let reader = CSVReader(stream)
//创建格式化的解析参数
let format: CSVParseFormat = CSVParseFormat.DEFAULT.setSkipHeaderRecord(true).setFirstLineAsHeader(true)
//创建解析器
let csvParser = CSVParser(reader, format)
//遍历每一行解析记录
for (csvRecord in csvParser) {
let rowNo = csvRecord.getRecordNumber()
//使用表头标题获取对应列的值
let id = csvRecord.get("id",csvParser.getHeaderDict()) ?? ""
let name = csvRecord.get("name",csvParser.getHeaderDict()) ?? ""
//使用列序号获取对应列的值
let age = csvRecord.get(2)
let remark = csvRecord.get(3)
if (let Some(comment) = csvRecord.getComment()) {
println(
"RowNo:${rowNo}|Id:${id}|name:${name}|age:${age}|remark:${remark}|comment:${comment}")
} else {
println("RowNo:${rowNo}|Id:${id}|name:${name}|age:${age}|remark:${remark}")
}
}
fileStream.close()
}
}
//Json格式输出
func serialPrintingDemo(fileName: String) {
//创建文件流
let fileStream = File(fileName, OpenMode.Read)
if (fileStream.canRead()) {
//创建字符读取的解析流
let stream = UTF8ReaderStream(fileStream)
let reader = CSVReader(stream)
//创建格式化的解析参数
let format: CSVParseFormat = CSVParseFormat.DEFAULT.setCommentMarker(r'α').setDelimiter("𪧘𪧘")
//创建解析器
let csvParser = CSVParser(reader, format)
let recordList = csvParser.parseRecordsToEnd()
//遍历每一行解析记录
for (csvRecord in recordList) {
println(csvRecord.serialize().toJson())
CSVRecord.deserialize(csvRecord.serialize())
}
fileStream.close()
}
}
//按照csv格式输出
func csvPrint() {
let csvContent =
###"# Comment before header
author,title,publishDate
Dan Simmons,Hyperion,"1989"
# Comment Line 1
# Comment Line 2
# Comment Line 3
Douglas Adams,The Hitchhiker's \"Guide\" to the Galaxy,1979
Douglas John,The Hitchhiker's \"Guide\" to the Mars,1979"###
//创建字符串流
let readerStream = StringStream(csvContent)
let reader = CSVReader(readerStream)
//创建格式化的解析参数
let format: CSVParseFormat = CSVParseFormat.DEFAULT
//创建解析器
let csvParser = CSVParser(reader, format)
let recordList = csvParser.parseRecordsToEnd()
let outFormat = CSVOutFormat.DEFAULT
let sbOut = StringBuilder()
let csvPrint = CSVPrinter(outFormat)
var firstLine = true
//遍历每一行解析记录
for (csvRecord in recordList) {
if (firstLine) {
firstLine = false
csvPrint.print(csvRecord, sbOut)
} else {
csvPrint.printLine(sbOut)
csvPrint.print(csvRecord, sbOut)
}
}
println(sbOut.toString())
}
执行结果呈现如下:
自定义输出:
RowNo:1|Id:30020|name:biboo|age:28|remark:middle school student
RowNo:2|Id:30021|name:张飞|age:45|remark:三国演义男4号𥻗𪧘
RowNo:3|Id:30022|name:关 羽|age:48|remark:著名的武财神αβγ|comment:这是第3行的注释,里面有转义的tab键和引用符号
RowNo:4|Id:30023|name:刘备|age:50|remark:胳膊比较长,善于编草鞋
Json输出:
{"recordNumber":1,"values":["id,name,age,remark"],"comment":null}
{"recordNumber":2,"values":["30020,biboo,28,middle school student"],"comment":null}
{"recordNumber":3,"values":["30021,张飞,45,三国演义男4号𥻗𪧘"],"comment":null}
{"recordNumber":4,"values":["#这是第3行的注释,里面有转义的tab键和引用符号"],"comment":null}
{"recordNumber":5,"values":["30022,关\t羽,48,著名的武财神αβγ"],"comment":null}
{"recordNumber":6,"values":["30023,刘备,50,\"胳膊比较长,善于编草鞋\""],"comment":null}
CSV自定义格式输出:
author,title,publishDate
[Dan Simmons,Hyperion,1989
Douglas Adams,"The Hitchhiker's \"Guide\" to the Galaxy",1979
Douglas John,"The Hitchhiker's \"Guide\" to the Mars",1979
性能测试
性能测试示例请见samples目录。
其中csv_perf为解析与写入测试,该测试针对一个包含43538条全国街道信息的CSV文件进行解析,并根据是否使用缓冲区来执行输出,具体结果如下:
注:实际使用时间可能会因执行环境的不同而有所变化。
一共解析了43538条记录,使用了313ms334us400ns时间
一共写入了43538条记录,使用了962ms50us500ns时间
一共写入了43538条记录,使用了121ms331us400ns时间
约束与限制
本规范已通过以下版本验证:
仓颉版本:1.0.0
开源协议
本项目采用 Apache License 2.0 协议,欢迎自由使用并参与开源事业。
![]()