C++中如何声明并初始化arrow::RandomAccessFile?解决编译错误
解决Parquet C++中RandomAccessFile共享指针初始化的问题
错误原因分析
- ARROW_ASSIGN_OR_RAISE宏使用错误:该宏要求所在函数的返回类型必须是
arrow::Status,如果你的函数返回int或其他非Status类型,宏在错误时返回的Status会和函数返回类型不匹配,从而触发“无法将const arrow::Status转换为int返回”的错误。 - 抽象类实例化错误:
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
相关产品推荐
相关产品推荐

