ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

Apache Arrow C++ 文件格式 API 全景:CSV / JSON / Parquet / ORC 读写指南

Apache Arrow C++ 文件格式 API 全景:CSV / JSON / Parquet / ORC 读写指南 Apache Arrow C 文件格式 API 全景CSV / JSON / Parquet / ORC 读写指南【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrowApache Arrow C 提供了一整套面向内存分析场景的文件格式读写 API覆盖 CSV、行分隔 JSONline-separated JSON、Parquet 与 ORC 四种主流格式。本文以仓库中的 formats.rst 文档为骨架结合 cpp/src/arrow/csv、cpp/src/arrow/json、cpp/src/parquet 与 cpp/src/arrow/adapters/orc 下的源码实现系统梳理每种格式的核心类、配置选项、工厂函数与流式读写方式。读完本文你将能够按需选择格式、配置正确的 Options 结构并熟练使用TableReader、StreamingReader、FileReader、FileWriter等 API 完成从文件到 Arrow 数据Table / RecordBatch的双向转换。CSV 读取从纯文本到类型化的 Arrow TableCSV 是数据交换中使用最广泛的文本格式。Arrow C 的 CSV 读取管线在 cpp/src/arrow/csv 目录中实现对外暴露三类 Options 结构与两类 Reader 类全部声明于 options.h 与 reader.h。三个读取阶段与对应的 OptionsCSV 读取被拆分为“解析parsing→ 类型推断与转换conversion→ 读取调度reading”三个阶段分别由ParseOptions、ConvertOptions和ReadOptions控制ParseOptions控制词法层面的解析规则即如何把字节流切分成字段与记录。核心字段包括字段默认值含义delimiter,字段分隔符quotingtrue是否启用引号包裹quote_char引号字符quoting为 true 时生效double_quotetrue值内的引号是否以双写引号转义escapingfalse是否启用反斜杠转义escape_char\\即kDefaultEscapeChar转义字符escaping为 true 时生效newlines_in_valuesfalse值内是否允许包含 CR/LF 换行ignore_empty_linestrue是否忽略空行为 false 时空行表示单列 CSV 中的一个空值invalid_row_handler无对列数不匹配的行的处理器pad_short_rowsfalse列数不足的行是否用 null 补齐ignore_extra_columnsfalse列数超出的行是否忽略多余列ConvertOptions控制从文本值到 Arrow 数据类型的转换。默认启用 UTF-8 校验check_utf8 truecolumn_types可以按列名显式指定类型从而跳过该列的类型推断default_column_type则为所有未显式指定的列提供默认类型一旦设置将禁用全部列的推断。空值/布尔值通过null_values、true_values、false_values三个字符串列表识别strings_can_be_null决定字符串列中的空值标记是否真的转换为 null默认 false而quoted_strings_can_be_null决定带引号的值是否也可以判空默认 true。auto_dict_encode与auto_dict_max_cardinality默认 50用于自动字典编码当类型推断发现字符串/二进制列时若该块内不同值数量不超过上限则按字典编码超过后回退为常规编码。decimal_point指定浮点与小数的十进制小数点字符默认.。include_columns按给定顺序只读取指定列include_missing_columns决定缺失列是报错false还是生成 null 列true。timestamp_parsers允许注入自定义时间戳解析器默认使用内置 ISO-8601 解析器。各 Options 均提供Defaults()工厂方法与Validate()校验入口。ReadOptions控制读取调度。use_threads默认 true决定是否使用全局 CPU 线程池并行解析block_size默认 1 MiB是从 IO 层请求的块大小同时决定多线程粒度与单个 RecordBatch 的大小skip_rows指定在列名行之前跳过的头部行数skip_rows_after_names指定读取列名后跳过的行数column_names可显式指定列名为空时若autogenerate_column_names为 true 则生成f0、f1… 形式的列名否则从首行读取。TableReader 与 StreamingReaderTableReader一次性把整个 CSV 文件读入arrow::Table。通过静态工厂Make(io_context, input, read_options, parse_options, convert_options)创建提供同步Read()与异步ReadAsync()两个入口。StreamingReader增量式读取继承RecordBatchReader每次产出一个RecordBatch。需要注意其实现约束目前始终单线程忽略use_threads且类型推断只在第一个块上进行、之后类型冻结——因此要么把block_size调大要么用ConvertOptions::column_types显式指定类型避免后续块类型不一致。它提供bytes_read()返回已处理字节数创建接口包括同步Make与异步MakeAsync。此外还有CountRowsAsync用于统计 CSV 文件的逻辑行数即读成表后的行数适合在正式读取前估算规模。CSV 写入把 Table / RecordBatch 序列化为 CSV 文本CSV 写入的格式化规则与选项定义在 writer.h 与 options.h 中。从源码注释可以确认其输出规则非二进制类型的值不加引号null 表示为空字符串二进制类型的所有非 null 数据加引号内部引号再以引号转义null 值为空且不加引号。WriteOptions 与 QuotingStyleWriteOptions 的核心字段字段默认值含义include_headertrue是否写出列名头行batch_size1024一次处理的批大小影响转换与写入性能delimiter,字段分隔符null_string空写入 null 值的字符串不允许含引号eol\n行结束符quoting_styleNeeded值的引号风格quoting_headerNeeded表头的引号风格QuotingStyle 枚举提供三种策略Needed只对渲染后可能含引号的值如字符串/二进制加引号AllValid对所有有效值加引号null 不加可能让按推断 schema 读取的 reader 把全部值当作字符串None不加任何引号但按 RFC4180 禁止值内含引号、分隔符与换行否则写入时报错。高层函数与增量 Writercsv-write-functions组writer.h提供三个重载的WriteCSV函数分别接受Table、RecordBatch与RecordBatchReader一次性写出到arrow::io::OutputStream。csv-writer-factories组提供MakeCSVWriter基于输出流与目标 Schema 创建实现ipc::RecordBatchWriter接口的增量写入器适合边产出边写如从其他格式转换而来。需要说明文档标注这些写入函数目前为实验性 API。行分隔 JSON流式对象到 Table 的转换Arrow C 的 JSON 支持面向“每行一个 JSON 对象”的行分隔 JSONNDJSON文件实现位于 cpp/src/arrow/json核心选项与读取器分别声明在 options.h 与 reader.h。ParseOptions 与 UnexpectedFieldBehaviorParseOptions.explicit_schema显式指定 Schema命中字段将跳过类型推断ParseOptions.newlines_in_values是否允许对象跨多行例如 pretty-printed JSON开启后解析会变慢UnexpectedFieldBehavior 枚举控制显式 Schema 之外字段的处理方式Ignore忽略、Error报错、InferType推断类型并纳入输出默认值。ReadOptions.use_threads默认 true与block_size默认 1 MiB同时决定多线程分块大小与 CSV 的语义一致。TableReader、StreamingReader 与 ParseOneTableReader通过Make(pool, input, read_options, parse_options)创建Read()一次性返回整个Table。StreamingReader按block_size固定块大小从流中读取每块转换为一个RecordBatch产出的批次 Schema 一致但行数可能不同。其 Schema 在首个非空块后冻结若使用InferType未预知字段只在第一块做推断之后按错误处理。启用线程时各块的解析/解码任务在cpu_executor上并行未提供时用全局线程池并带有与执行器容量对应的预读禁用线程时全部在调用线程执行。bytes_processed()返回已成功转换并消费的字节数Make/MakeAsync分别提供同步与异步创建。模块还提供独立的ParseOne函数把单个 JSON Buffer 解析为一个RecordBatch适合处理单块数据。Parquet 读取列式存储的高效还原Parquet 是 Arrow 生态中与列式内存格式最契合的磁盘格式。读取侧 API 分布在 cpp/src/parquet/properties.h、cpp/src/parquet/arrow/reader.h 与 cpp/src/parquet/stream_reader.h。ReaderProperties底层文件读取控制ReaderProperties 面向 Parquet 文件本身关键控制点包括内存池构造时默认使用arrow::default_memory_pool()缓冲流enable_buffered_stream()/disable_buffered_stream()决定是否把ReadAt调用包装进固定大小缓冲区主要目的不是性能而是内存资源控制缓冲区大小由set_buffer_size()调整默认kDefaultBufferSize 16 KiBThrift 限制set_thrift_string_size_limit()默认 1 亿字节与set_thrift_container_size_limit()默认 100 万用于防止“空间/时间炸弹”读超大头部文件时可能需要调大Schema 深度限制set_schema_depth_limit()默认 100防止重建嵌套 Schema 时递归过深导致栈溢出DoS 防护页校验set_page_checksum_verification()启用页级 CRC 校验Footer 读取大小set_footer_read_size()默认 64 KiB见kDefaultFooterReadSize控制从文件尾部读取元数据的大小对高延迟文件系统和大元数据文件可减少往返次数解密属性file_decryption_properties()注入文件解密配置模块级函数default_reader_properties()返回带默认值的属性对象。ParquetFileReader 与 FileReader两级读取模型ParquetFileReader 是纯 Parquet 层的读取器schema、row group、列块元数据层面不对应 Arrow 类型arrow::FileReader 是 Arrow 层封装提供ReadTable()全量或按列索引投影读取、ReadRowGroup(i)/ReadRowGroups(...)按行组读取、GetColumn(i, ...)与ReadColumn(i, ...)单列读取、GetRecordBatchReader(...)按行组/列索引组合产出批次流以及ScanContents(...)单线程扫描统计行数。set_use_threads()控制多列并行读取默认单线程set_batch_size()控制 RecordBatchReader 每批行数。ArrowReaderProperties 与 FileReaderBuilderArrowReaderProperties承载 Arrow 特有读取偏好如类型转换策略。FileReaderBuilder 是推荐的构建入口Open(file, reader_properties, metadata)从 ArrowRandomAccessFile打开OpenFile(path, memory_map, props, metadata)直接从文件路径打开可选内存映射memory_pool(pool)指定 Arrow 内存池properties(arg_properties)设置 Arrow 读取属性Build()产出FileReader。另有parquet-arrow-reader-factories组中的便捷函数OpenFile(random_access_file, memory_pool)直接返回FileReader。StreamReader面向标量读的流式接口StreamReader 提供operator风格的顺序读取支持bool、各类整数、float/double、char、std::chrono::milliseconds/microseconds及定长字符数组等基础类型配合eof()、current_column()、current_row()、num_rows()等状态查询适合按行顺序消费数据。当前实现不支持 repeated 字段列表/嵌套重复列。Parquet 写入从 Arrow Table 到列式文件写入侧核心是 WriterProperties、ArrowWriterProperties以及 arrow::FileWriter。WriterProperties 与 Builder 模式WriterProperties通过内部Builder链式配置默认值可在 properties.h 的常量中确认配置项Builder 方法默认值数据页大小data_pagesize()1 MiBkDefaultDataPageSize每页最大行数max_rows_per_page()20,000字典编码enable_dictionary()/disable_dictionary()可精确到列路径启用字典页大小上限dictionary_pagesize_limit()1 MiB写入批大小write_batch_size()1024行组最大行数max_row_group_length()1,048,5761 Mi 行统计信息statistics相关配置启用DEFAULT_MAX_STATISTICS_SIZE 4096文件版本version()PARQUET_2_6源码中 Builder 默认值数据页版本data_page_version()V1V2 存在历史兼容问题见ParquetDataPageVersion注释压缩compression()/compression_level()默认不压缩页索引page_index_enabled()默认启用页校验和page_checksum_enabled()默认关闭布隆过滤器set_bloom_filter_options()每列可选默认fpp 0.05、fold trueColumnProperties允许逐列覆盖编码、压缩、字典、统计、页索引与布隆过滤器set_bloom_filter_options会校验 fpp 必须在(0.0, 1.0)、ndv 必须非负。此外还有实验性的内容定义分块CDCCdcOptions与SizeStatisticsLevel统计级别配置以及默认导出函数default_writer_properties()。FileWriter、WriteTable 与 StreamWriterarrow::FileWriter通过Open(schema, pool, sink, properties, arrow_properties)创建。WriteTable(table, chunk_size)一次写入一张表chunk_size默认即行组最大行数NewRowGroup()/NewBufferedRowGroup()控制行组边界WriteColumnChunk(...)按列写块WriteRecordBatch(...)把多个批次累积进缓冲行组受max_row_group_length约束。Close()写出 footer 并关闭文件之后可通过metadata()取得文件元数据AddKeyValueMetadata()可附加键值元数据——注意若启用store_schemaARROW:schema键会被占用覆盖该键会使读侧无法恢复 Arrow Schema。WriteTable文档单独列出的高层便捷函数一张表一次写出适用于“一次性落盘”场景需要迭代写多张表时改用FileWriter。StreamWriter与StreamReader对称用operator顺序写基础类型值适合流式生成数据。ORC面向 Hive 生态的列式格式适配ORC 支持通过 cpp/src/arrow/adapters/orc 适配层接入核心类为ORCFileReader与ORCFileWriter选项结构定义在 options.h。ORCFileReaderStripe 级读取ORCFileReader 由Open(random_access_file, pool)创建读出的Table每个 stripe 对应一个 RecordBatch。主要能力ReadSchema()读取文件 SchemaRead()系列支持按整个表、按显式 Schema、按列索引include_indices或按列名include_names投影读取ReadStripe(stripe, ...)读取单个 stripeNextStripeReader(batch_size, ...)返回当前 stripe 的细粒度批次迭代器避免ReadStripe把整个 stripe 载入内存导致 OOMGetRecordBatchReader(batch_size, include_names)提供全文件迭代Seek(row_number)支持定位到指定行元数据查询丰富NumberOfStripes()、NumberOfRows()、GetStripeInformation(i)返回含offset、length、num_rows的StripeInformation、GetFileVersion()当前已知 0.11 与 0.12、GetSoftwareVersion()、GetCompression()、GetRowIndexStride()、GetWriterId()等GetSerializedFileTail()可序列化文件尾部供其他 reader 复用避免重复读取ReadMetadata()返回 ORC 元数据。WriteOptions 与 ORCFileWriterWriteOptions 控制写入行为字段默认值含义batch_size1024每次写入的行数file_versionFileVersion(0, 12)ORC 文件版本stripe_size64 MiB每个 stripe 的字节大小compressionUNCOMPRESSED压缩编解码器compression_block_size64 KiB压缩块大小compression_strategykSpeed压缩策略速度优先还是压缩率优先row_index_stride10000行索引中每项覆盖的行数padding_tolerance0.0填充容差dictionary_key_size_threshold0.0字典编码阈值0 禁用、1 始终启用bloom_filter_columns空启用布隆过滤器的列bloom_filter_fpp0.05布隆过滤器假阳性率上限ORCFileWriter 通过Open(output_stream, write_options)创建支持多次Write(table)或Write(record_batch)后续调用必须与首次 Schema 一致最后Close()关闭底层orc::Writer并完成文件收尾。四种格式的选型与阅读路径建议结合本仓库的实现特点可按以下维度选择格式CSV / JSON面向文本互操作与外部数据导入无内建列式压缩读入后统一转为 Arrow 内存格式CSV 关注ParseOptions的词法细节与ConvertOptions的类型推断JSON 关注UnexpectedFieldBehavior与explicit_schemaParquetArrow 列式生态的“首选落盘格式”支持谓词下推友好的页索引、统计、布隆过滤器、字典编码与行组级随机访问推荐通过FileReaderBuilder装配读取、通过WriterProperties::Builder装配写入ORC面向 Hive/Spark 等 Hadoop 生态的列式格式stripe 与行索引结构与 Parquet 不同通过适配层读取写入由WriteOptions控制压缩与索引参数。在仓库中可进一步阅读CSV 完整示例见 cpp/examples 下的相关示例与 c_glib/test 中的 Ruby 绑定测试Parquet 的读写测试覆盖于 cpp/src/parquet 下的*_test.ccORC 适配测试位于 cpp/src/arrow/adapters/orc。所有 Options 结构均实现了Defaults()与Validate()建议在自定义配置后调用Validate()提前发现非法组合。【免费下载链接】arrowApache Arrow is the universal columnar format and multi-language toolbox for fast data interchange and in-memory analytics项目地址: https://gitcode.com/GitHub_Trending/arrow3/arrow创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表