如何在C++中反序列化读取Java序列化的Apache Arrow VectorSchemaRoot数据
解决方案
你Java侧使用的是标准Arrow IPC流格式序列化数据,C++侧直接调用Arrow官方提供的IPC流读取接口即可完成反序列化,完整实现逻辑如下:
前置依赖
需要先引入Arrow C++核心库,链接arrow_shared依赖,引入必要头文件:
#include <arrow/api.h> #include <arrow/ipc/api.h> #include <iostream>
完整实现代码
std::string bytes; // 已获取的序列化后字节数据 // 步骤1:将std::string包装为Arrow Buffer,默认不拷贝内存,性能更高 std::shared_ptr<arrow::Buffer> buffer = arrow::Buffer::FromString(bytes); // 步骤2:构造Buffer输入流对接IPC读取接口 std::shared_ptr<arrow::io::BufferReader> buffer_reader = std::make_shared<arrow::io::BufferReader>(buffer); // 步骤3:打开IPC流读取器 arrow::Result<std::shared_ptr<arrow::ipc::RecordBatchReader>> reader_result = arrow::ipc::RecordBatchStreamReader::Open(buffer_reader); if (!reader_result.ok()) { // 自定义错误处理逻辑,比如格式校验失败 std::cerr << "打开IPC流失败: " << reader_result.status().message() << std::endl; return; } std::shared_ptr<arrow::ipc::RecordBatchReader> reader = *reader_result; // 步骤4:获取表结构Schema(可选,可用于字段合法性校验) std::shared_ptr<arrow::Schema> schema = reader->schema(); std::cout << "读取到的表结构:" << schema->ToString() << std::endl; // 步骤5:读取数据批次 arrow::Result<std::shared_ptr<arrow::RecordBatch>> batch_result = reader->Next(); while (batch_result.ok() && *batch_result != nullptr) { std::shared_ptr<arrow::RecordBatch> batch = *batch_result; std::cout << "读取到数据批次,行数:" << batch->num_rows() << std::endl; // 示例:读取第0列的Int32类型数据,其他类型按对应Array类转换即可 if (batch->column(0)->type()->id() == arrow::Type::INT32) { auto int32_array = std::static_pointer_cast<arrow::Int32Array>(batch->column(0)); for (int i = 0; i < int32_array->length(); i++) { if (!int32_array->IsNull(i)) { std::cout << "第" << i << "行值:" << int32_array->Value(i) << std::endl; } } } // 读取下一个批次 batch_result = reader->Next(); } if (!batch_result.status().ok()) { std::cerr << "读取数据批次失败: " << batch_result.status().message() << std::endl; }
注意事项
- 你Java侧只调用了一次
writeBatch(),所以C++侧只会读到1个数据批次,如果后续Java侧会写入多个批次,上述循环读取逻辑可直接兼容。 Buffer::FromString不会拷贝std::string的底层内存,只要保证读取数据的过程中bytes对象不被释放即可,如果需要独立生命周期可使用Buffer::Copy接口拷贝内存。- 不同数据类型的数组读取对应不同的Arrow Array类:字符串对应
arrow::StringArray、单精度浮点数对应arrow::FloatArray、双精度浮点数对应arrow::DoubleArray,以此类推。
内容的提问来源于stack exchange,提问作者user2183336
相关产品推荐
相关产品推荐

