简体   繁体   中英

How is Java Path converted to e.g. InputStream

The java.nio.Files class has a static method named Files#newInputStream, which takes a Path instance as an input and returns an InputStream as an output. But it is unclear to me how this can be done without instantiating a File(InputStream) object. I would like to be able to make my own implementation of Path which can point to an InputStream which is not related to a File object. I would like to do this so that I can make a virtual filesystem which uses the notation of filesystems without actually depending on a filesystem. Is this possible?

The Java NIO file system API uses delegation and abstract factory patterns. At the lowest level there's the implementation of 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 provides instances of 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.

And then there's the Path interface:

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

Note that a Path is just that, a path. It does not necessarily represent an actual file, only the path of the file (whether it exists or not). It's similar to java.io.File in this regard.

When you invoke methods in the Files class it uses the Path#getFileSystem() and FileSystem#provider() methods to delegate to the FileSystemProvider . This API design is what allows a developer to use the Files class with any implementation of Path in a transparent manner. It doesn't matter to the developer how that InputStream is created, only that the InputStream is created in a way consistent with the API's contracts.

The methods Paths#get(String,String...) and Path#of(String,String...) delegate to the default file system to create the instance of Path . When you use those Path instances with the methods in Files you end up accessing the host platform's underlying file system.

If you want to create a virtual file system then you need to implement a FileSystemProvider along with all the related abstract classes and interfaces, such as FileSystem and Path . Though note some of the API is "optional". If your implementation doesn't provide the optional API then you can throw an UnsupportedOperationException . The Javadoc of the various classes/methods gives more information.

That said, there's already an in-memory file system implementation out there: https://github.com/google/jimfs


" But it is unclear to me how this can be done without instantiating a File(InputStream) ". The NIO file API is not related to java.io.File . If you want to see how it does what it does you can look at the source code. Your JDK should have come with a src.zip file which contains the Java source files; however, it will only contain the implementation for your host operating system and won't contain any of the native code (the default file systems ultimately use native code to communicate with the underlying OS' file system).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM