输入/输出和文件系统#
Arrow 提供了一系列 C++ 接口,用于抽象输入/输出操作的具体细节。 它们操作的是无类型二进制数据流。 这些抽象用于各种目的,例如读取 CSV 或 Parquet 数据、传输 IPC 流等等。
另请参阅
读取二进制数据#
读取二进制数据的接口有两种形式
顺序读取:
InputStream
接口提供Read
方法; 建议Read
到Buffer
,因为它在某些情况下可以避免内存复制。随机访问读取:
RandomAccessFile
接口提供额外的定位工具,最重要的是ReadAt
方法,允许从多个线程并行读取。
具体实现可用于 内存中 读取
、非缓冲 文件 读取
、内存映射 文件 读取
、缓冲 读取
、压缩 读取
。
写入二进制数据#
写入二进制数据主要通过 OutputStream
接口完成。
具体实现可用于 内存中 写入
、非缓冲 文件 写入
、内存映射 文件 写入
、缓冲 写入
、压缩 写入
。
文件系统#
文件系统 接口
允许对各种数据存储后端(例如本地文件系统或 S3 bucket)进行抽象访问。 它提供输入和输出流以及目录操作。
另请参阅
文件系统接口公开了底层数据存储的简化视图。 数据路径表示为抽象路径,即使在 Windows 上,抽象路径也使用 /
分隔,并且不应包含特殊的路径组件,例如 .
和 ..
。 符号链接(如果底层存储支持)会自动取消引用。 只有关于文件条目的基本 metadata
(例如文件大小和修改时间)可用。
可以使用 FromUri 工厂之一从 URI 字符串构造文件系统实例,这些工厂根据 URI 的 scheme
调度到特定于实现的工厂。 新实例的其他属性是从 URI 的其他属性(例如 hostname
、username
等)中提取的。 Arrow 支持运行时注册新文件系统,并为几个文件系统提供内置支持。
支持哪些内置文件系统是在构建时配置的,可能包括 本地 文件系统 访问
、HDFS
、Amazon S3 兼容 存储
和 Google Cloud Storage
。
注意
使用文件系统的任务通常会在 I/O 线程池上运行。 对于支持高并发性的文件系统,增加 I/O 线程池的大小可能会带来好处。
定义新的文件系统#
通过为每个新 URI 方案注册一个工厂,可以使用 RegisterFileSystemFactory()
将对其他 URI 方案的支持添加到 FromUri 工厂。 为了启用自动注册的首选常见情况,可以在命名空间范围内定义 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()
所依赖的符号存在。