输入/输出与文件系统#
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 线程池的大小可能会带来收益。
定义新的文件系统#
可以通过使用 RegisterFileSystemFactory() 为每个新的 URI 方案注册工厂,从而将对额外 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() 所依赖的符号。