You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 23:24:00