输入/输出和文件系统#
Arrow 提供了一系列 C++ 接口,抽象了输入/输出操作的具体细节。它们在无类型二进制数据流上运行。这些抽象用于各种目的,例如读取 CSV 或 Parquet 数据、传输 IPC 流等等。
另请参阅
读取二进制数据#
用于读取二进制数据的接口有两种形式
顺序读取:
InputStream
接口提供Read
方法;建议将Read
到Buffer
中,因为它在某些情况下可以避免内存复制。随机访问读取:
RandomAccessFile
接口提供用于定位的额外设施,最重要的是ReadAt
方法,它允许从多个线程并行读取。
写入二进制数据#
写入二进制数据主要通过 OutputStream
接口完成。
文件系统#
文件系统接口
允许对各种数据存储后端进行抽象访问,例如本地文件系统或 S3 存储桶。它提供输入和输出流以及目录操作。
另请参阅
文件系统接口公开了对底层数据存储的简化视图。数据路径表示为抽象路径,即使在 Windows 上也是 /
分隔的,并且不应该包含特殊路径组件,例如 .
和 ..
。如果底层存储支持符号链接,则会自动取消引用它们。仅提供有关文件条目基本 元数据
,例如文件大小和修改时间。
文件系统实例可以使用 FromUri 工厂 从 URI 字符串构造,这些工厂会根据 URI 的 scheme
分派到特定于实现的工厂。新实例的其他属性是从 URI 的其他属性中提取的,例如 hostname
、username
等等。Arrow 支持运行时注册新的文件系统,并提供对几个文件系统的内置支持。
哪些内置文件系统受支持是在构建时配置的,可能包括 本地文件系统访问
、HDFS
、Amazon S3 兼容存储
和 Google Cloud Storage
。
注意
使用文件系统的任务通常在 I/O 线程池 上运行。对于支持高并发级别的文件系统,您可以从增加 I/O 线程池的大小中获益。
定义新的文件系统#
可以通过为每个新的 URI 方案注册一个工厂来向 FromUri 工厂 添加对其他 URI 方案的支持,使用 RegisterFileSystemFactory()
。为了启用更常见的注册自动优先的情况,可以在命名空间范围内定义 FileSystemRegistrar
的实例,该实例会在实例加载时注册工厂
auto kExampleFileSystemModule = ARROW_REGISTER_FILESYSTEM(
"example",
[](const Uri& uri, const io::IOContext& io_context,
std::string* out_path) -> Result<std::shared_ptr<arrow::fs::FileSystem>> {
EnsureExampleFileSystemInitialized();
return std::make_shared<ExampleFileSystem>();
},
&EnsureExampleFileSystemFinalized
);
如果文件系统实现需要在任何实例构建之前初始化,则应将其包含在相应的工厂中,或在调用工厂之前以其他方式自动确保。同样,如果文件系统实现需要在进程结束之前进行拆卸,则可以将其包装在一个函数中,并与工厂一起注册。所有终结器都将由 EnsureFinalized()
调用。
通过将文件系统实现隔离开来,可以减少构建复杂性,隔离开来形成一个单独的共享库,应用程序可以链接或动态加载。Arrow 的内置文件系统实现也遵循这种模式。如果包含 FileSystemRegistrar
实例的共享库必须动态加载,则应使用 LoadFileSystemFactories()
加载它。如果这样的库可能会静态链接到 arrow,它应该在其源代码中只有一个 #include "arrow/filesystem/filesystem_library.h"
,以确保存在 LoadFileSystemFactories()
依赖的符号。