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

C++中如何声明并初始化arrow::RandomAccessFile?解决编译错误

解决Parquet C++中RandomAccessFile共享指针初始化的问题

错误原因分析

  1. ARROW_ASSIGN_OR_RAISE宏使用错误:该宏要求所在函数的返回类型必须是arrow::Status,如果你的函数返回int或其他非Status类型,宏在错误时返回的Status会和函数返回类型不匹配,从而触发“无法将const arrow::Status转换为int返回”的错误。
  2. 抽象类实例化错误:arrow::io::RandomAccessFile是抽象基类,不能直接用std::make_shared创建实例。你试图用ReadableFile::Open的结果构造它,本质是在尝试实例化抽象类,必然报错。

正确的初始化方式

方式一:在返回Status的函数中使用ARROW_ASSIGN_OR_RAISE

这是Arrow官方推荐的用法,适用于以arrow::Status为返回值的函数:

#include <arrow/io/file.h>
#include <parquet/arrow/reader.h>
#include <iostream>

arrow::Status GetParquetColumnMin(const std::string& parquet_path, int column_idx) {
    // 直接获取ReadableFile实例(它是RandomAccessFile的子类),自动完成基类指针的转换
    ARROW_ASSIGN_OR_RAISE(auto input, arrow::io::ReadableFile::Open(parquet_path));

    // 初始化Parquet FileReader
    std::unique_ptr<parquet::arrow::FileReader> reader;
    ARROW_RETURN_NOT_OK(parquet::arrow::OpenFile(input, arrow::default_memory_pool(), &reader));

    // 读取目标列数据
    std::shared_ptr<arrow::ChunkedArray> column_data;
    ARROW_RETURN_NOT_OK(reader->ReadColumn(column_idx, &column_data));

    // 计算并输出最小值(示例针对数值类型列)
    std::shared_ptr<arrow::Scalar> min_val;
    ARROW_RETURN_NOT_OK(column_data->Min(&min_val));
    if (min_val) {
        std::cout << "Column " << column_idx << " min value: " << min_val->ToString() << std::endl;
    }

    return arrow::Status::OK();
}

方式二:手动处理Result(适用于非返回Status的函数)

如果你的函数不能返回arrow::Status(比如main函数),需要手动检查操作状态:

#include <arrow/io/file.h>
#include <parquet/arrow/reader.h>
#include <iostream>

int main() {
    std::string parquet_path = "target_file.parquet";
    std::shared_ptr<arrow::io::RandomAccessFile> input;

    // 手动处理文件打开结果
    auto open_result = arrow::io::ReadableFile::Open(parquet_path);
    if (!open_result.ok()) {
        std::cerr << "Open file failed: " << open_result.status().ToString() << std::endl;
        return 1;
    }
    // 子类指针隐式转换为基类指针
    input = *open_result;

    // 初始化FileReader
    std::unique_ptr<parquet::arrow::FileReader> reader;
    auto reader_status = parquet::arrow::OpenFile(input, arrow::default_memory_pool(), &reader);
    if (!reader_status.ok()) {
        std::cerr << "Create reader failed: " << reader_status.ToString() << std::endl;
        return 1;
    }

    // 读取列并计算最小值的逻辑和方式一一致
    std::shared_ptr<arrow::ChunkedArray> column_data;
    if (!reader->ReadColumn(0, &column_data).ok()) {
        std::cerr << "Read column failed" << std::endl;
        return 1;
    }

    std::shared_ptr<arrow::Scalar> min_val;
    if (column_data->Min(&min_val).ok() && min_val) {
        std::cout << "Column 0 min value: " << min_val->ToString() << std::endl;
    }

    return 0;
}

核心要点

  • arrow::io::ReadableFile是RandomAccessFile的具体实现子类,ReadableFile::Open返回的Result<std::shared_ptr<ReadableFile>>可以直接赋值给std::shared_ptr<arrow::io::RandomAccessFile>,利用C++的多态特性。
  • 所有Arrow的IO操作都会返回Result或Status类型,必须严格检查操作状态,避免未处理的错误导致程序崩溃。

内容的提问来源于stack exchange,提问作者roschach

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:46:19