读取和写入 ORC 文件#

Apache ORC 项目提供了一种标准化的开源列式存储格式,用于数据分析系统。它最初是为 Apache Hadoop 中的使用而创建的,系统如 Apache Drill、Apache Hive、Apache Impala 和 Apache Spark 将其作为高性能数据 I/O 的共享标准。

Apache Arrow 是正在使用 ORC 文件读取或写入的数据的理想内存表示层。

支持的 ORC 功能#

ORC 格式具有许多功能,我们支持其中的一部分。

数据类型#

以下是 ORC 类型和映射的 Arrow 类型列表。

逻辑类型

映射的 Arrow 类型

注释

BOOLEAN

布尔型

BYTE

Int8

SHORT

Int16

INT

Int32

LONG

Int64

FLOAT

Float32

DOUBLE

Float64

STRING

String/LargeString

(1)

BINARY

Binary/LargeBinary/FixedSizeBinary

(1)

TIMESTAMP

Timestamp/Date64

(1) (2)

TIMESTAMP_INSTANT

Timestamp

(2)

LIST

List/LargeList/FixedSizeList

(1)

MAP

Map

STRUCT

Struct

UNION

SparseUnion/DenseUnion

(1)

DECIMAL

Decimal128/Decimal256

(1)

DATE

Date32

VARCHAR

String

(3)

CHAR

String

(3)

  • (1) 在读取端,ORC 类型读取为表中第一个对应的 Arrow 类型。

  • (2) 在写入端,当提供时区时使用 ORC TIMESTAMP_INSTANT,否则使用 ORC TIMESTAMP。在读取端,ORC TIMESTAMP 和 TIMESTAMP_INSTANT 类型都读取为 Arrow Timestamp 类型,arrow::TimeUnit::NANO 且仅对于 ORC TIMESTAMP_INSTANT 类型,时区设置为 UTC。

  • (3) 在读取端,ORC CHAR 和 VARCHAR 类型都读取为 Arrow String 类型。写入端不支持 ORC CHAR 和 VARCHAR 类型。

压缩#

压缩编解码器

SNAPPY

GZIP/ZLIB

LZ4

ZSTD

不支持的压缩编解码器:LZO。

读取 ORC 文件#

ORCFileReader 类将整个文件或条带的数据读取到 ::arrow::Table 中。

ORCFileReader#

ORCFileReader 类需要一个表示输入文件的 ::arrow::io::RandomAccessFile 实例。

#include <arrow/adapters/orc/adapter.h>

{
    // ...
    arrow::Status st;
    arrow::MemoryPool* pool = default_memory_pool();
    std::shared_ptr<arrow::io::RandomAccessFile> input = ...;

    // Open ORC file reader
    auto maybe_reader = arrow::adapters::orc::ORCFileReader::Open(input, pool);
    if (!maybe_reader.ok()) {
        // Handle error instantiating file reader...
    }
    std::unique_ptr<arrow::adapters::orc::ORCFileReader> reader = maybe_reader.ValueOrDie();

    // Read entire file as a single Arrow table
    auto maybe_table = reader->Read();
    if (!maybe_table.ok()) {
        // Handle error reading ORC data...
    }
    std::shared_ptr<arrow::Table> table = maybe_table.ValueOrDie();
}

写入 ORC 文件#

ORCFileWriter#

ORC 文件写入到 OutputStream 中。

#include <arrow/adapters/orc/adapter.h>
{
    // Oneshot write
    // ...
    std::shared_ptr<arrow::io::OutputStream> output = ...;
    auto writer_options = WriterOptions();
    auto maybe_writer = arrow::adapters::orc::ORCFileWriter::Open(output.get(), writer_options);
    if (!maybe_writer.ok()) {
       // Handle error instantiating file writer...
    }
    std::unique_ptr<arrow::adapters::orc::ORCFileWriter> writer = maybe_writer.ValueOrDie();
    if (!(writer->Write(*input_table)).ok()) {
        // Handle write error...
    }
    if (!(writer->Close()).ok()) {
        // Handle close error...
    }
}