Java 路径如何转换为例如输入流

How is Java Path converted to e.g. InputStream

java.nio.Files class 有一个名为 Files#newInputStream 的静态方法,它将 Path 实例作为输入,returns InputStream 作为输出。但我不清楚如何在不实例化 File(InputStream) 对象的情况下完成此操作。我希望能够创建自己的 Path 实现,它可以指向与 File 对象无关的 InputStream。我想这样做,以便我可以创建一个虚拟文件系统,它使用文件系统的符号而不实际依赖于文件系统。这可能吗?

Java NIO 文件系统API 使用委托和抽象工厂模式。在最低级别有 java.nio.file.spi.FileSystemProvider:

的实现

Service-provider class for file systems. The methods defined by the Files class will typically delegate to an instance of this class. [emphasis added]

A FileSystemProvider 提供了 java.nio.file.FileSystem:

的实例

Provides an interface to a file system and is the factory for objects to access files and other objects in the file system.

The default file system, obtained by invoking the FileSystems.getDefault method, provides access to the file system that is accessible to the Java virtual machine. The FileSystems class defines methods to create file systems that provide access to other types of (custom) file systems.

A file system is the factory for several types of objects: [emphasis added]

  • The getPath method converts a system dependent path string, returning a Path object that may be used to locate and access a file.

  • The getPathMatcher method is used to create a PathMatcher that performs match operations on paths.

  • The getFileStores method returns an iterator over the underlying file-stores.

  • The getUserPrincipalLookupService method returns the UserPrincipalLookupService to lookup users or groups by name.

  • The newWatchService method creates a WatchService that may be used to watch objects for changes and events.

然后是Path界面:

An object that may be used to locate a file in a file system. It will typically represent a system dependent file path.

请注意,Path 就是一条路径。它不一定代表一个实际的文件,只代表文件的路径(不管它存在与否)。在这方面它类似于 java.io.File

当您调用 Files class 中的方法时,它使用 Path#getFileSystem() and FileSystem#provider() 方法委托给 FileSystemProvider。这种 API 设计允许开发人员以透明的方式将 Files class 与 Path 的任何实现 一起使用。 如何创建InputStream并不重要,只是InputStream是在中创建的与 API 的合同一致。​​

创建 Path 实例的方法 Paths#get(String,String...) and Path#of(String,String...) delegate to the default file system。当您将这些 Path 实例与 Files 中的方法一起使用时,您最终会访问主机平台的底层文件系统。

如果你想创建一个虚拟文件系统,那么你需要实现一个FileSystemProvider以及所有相关的抽象classes和接口,例如FileSystemPath。尽管注意一些 API 是 "optional"。如果您的实现不提供可选的 API,那么您可以抛出一个 UnsupportedOperationException。各种 classes/methods 的 Javadoc 提供了更多信息。

也就是说,已经有内存中文件系统实现:https://github.com/google/jimfs


"但我不清楚如何在不实例化 File(InputStream)" 的情况下完成此操作。 NIO 文件 API 与 java.io.File 无关。如果你想看看它是如何做的,你可以查看源代码。你的 JDK 应该有一个包含 Java 源文件的 src.zip 文件;但是,它只包含主机操作系统的实现,不包含任何本机代码(默认文件系统最终使用本机代码与底层 OS' 文件系统通信)。