FileSystem.openFile()/FileContext.openFile()

这是FileSystem和FileContext都提供的一个方法,用于高级文件打开选项,以及在实现时支持异步/延迟打开文件。

创建一个用于打开文件的构建器,支持标准和文件系统特定的选项。build()调用的返回值是一个Future,必须等待该结果。文件打开操作可能是异步的,实际上可能会延迟(包括权限/存在性检查),直到真正执行读取操作时才会进行。

该API调用在Hadoop 3.3.0版本中被添加到FileSystemFileContext中;在Hadoop 3.3.1版本中进行了如下优化。

FutureDataInputStreamBuilder openFile(Path path)

创建一个FutureDataInputStreamBuilder用于构建一个操作,以打开位于path路径的文件进行读取。

当在返回的FutureDataInputStreamBuilder实例上调用build()时,会验证构建器参数并调用FileSystem.openFileWithOptions(Path, OpenFileParameters)AbstractFileSystem.openFileWithOptions(Path, OpenFileParameters)

这些受保护的方法返回一个CompletableFuture,当调用其get()方法时,要么返回已打开文件内容的输入流,要么引发异常。

FileSystem.openFileWithOptions(PathHandle, OpenFileParameters)的基本实现最终会调用FileSystem.open(Path, int)

因此,链式调用 FileSystem.openFile(path).build().get()FileSystem.open(Path p, int bufferSize) 具有相同的前置条件和后置条件

然而,实现方式上存在一个可供自由利用的差异:

返回的流可能实现延迟打开,其中文件不存在或访问权限失败的问题可能直到实际数据的第一次read()才会显现。

这可以节省对象存储上的网络IO。

openFile() 操作可以在调用期间检查文件系统的状态,但由于文件系统状态可能在此调用与实际的 build()get() 操作之间发生变化,因此此处不得检查文件特定的前置条件(文件是否存在、文件是否可读等)。

未实现open(Path, int)的FileSystem实现可以选择延迟抛出UnsupportedOperationException异常,直到FutureDataInputStreamBuilder.build()或后续的get()调用时才抛出,否则它们也可以在openFile()调用时快速失败。

有关如何使用构建器以及可以传入的标准选项的详细信息,请参阅FutureDataInputStreamBuilder

FutureDataInputStreamBuilder openFile(PathHandle)

创建一个FutureDataInputStreamBuilder用于构建操作,以打开由给定PathHandle标识的文件进行读取。

如果由文件系统实现,openFile(Path)的语义将保持一致。因此调用链openFile(pathhandle).build().get()open(Pathhandle, int)具有相同的前置条件和后置条件。

未实现open(PathHandle handle, int bufferSize)的FileSystem实现可以选择延迟抛出UnsupportedOperationException异常,直到FutureDataInputStreamBuilder.build()或后续的get()调用时才抛出,否则它们可以在openFile(PathHandle)调用时快速失败。

基础实现在build()操作中会抛出此异常;其他实现应该复制此行为。

实现者说明

openFileWithOptions()的基本实现实际上是同步执行open(path)操作,但仍将结果或任何失败返回在CompletableFuture<>中,以便在所有文件系统中提供一致的生命周期。

对于任何文件系统客户端,如果打开文件的时间可能较长,则应通过在某些执行器/线程池中提交操作来异步执行。这尤其适用于对象存储和其他可能通过长距离连接访问的文件系统。

可以支持任意的文件系统特定选项;这些选项必须以文件系统模式为前缀,例如hdfs.或以fs.SCHEMA格式作为常规配置设置fs.hdfs。后一种样式允许相同的配置选项同时用于文件系统配置和文件特定配置。

应该能够在不指定任何选项的情况下始终打开文件,以便为用户提供一致的模型。然而,实现可以选择要求设置一个或多个强制选项。

返回的流可能会对文件访问执行“惰性”评估。这对于对象存储尤其重要,因为在这些存储中,存在性探测成本高昂,即使采用异步打开方式,也可能被视为不必要的操作。