Как Java Path преобразуется, например, в InputStream

Класс java.nio.Files имеет статический метод с именем Files # newInputStream, который принимает экземпляр Path в качестве входного и возвращает InputStream в качестве выходного. Но мне неясно, как это можно сделать без создания экземпляра объекта File (InputStream). Я хотел бы иметь возможность создать собственную реализацию Path, которая может указывать на InputStream, который не связан с объектом File. Я хотел бы сделать это, чтобы я мог создать виртуальную файловую систему, которая использует обозначения файловых систем, фактически не завися от файловой системы. Это возможно?

Всего 1 ответ


API файловой системы Java NIO использует шаблоны делегирования и абстрактной фабрики. На самом нижнем уровне находится реализация java.nio.file.spi.FileSystemProvider :

Класс сервис-провайдера для файловых систем. Методы, определенные классом Files , обычно делегируют экземпляру этого класса. [выделение добавлено]

FileSystemProvider предоставляет экземпляры java.nio.file.FileSystem :

Предоставляет интерфейс к файловой системе и является фабрикой для доступа объектов к файлам и другим объектам в файловой системе.

Файловая система по умолчанию, полученная путем вызова FileSystems.getDefault метода, обеспечивает доступ к файловой системе, доступные для виртуальной машины Java. Класс FileSystems определяет методы для создания файловых систем, которые предоставляют доступ к другим типам (пользовательских) файловых систем.

Файловая система - это фабрика для нескольких типов объектов: [выделение добавлено]

  • Метод getPath преобразует системно-зависимую строку пути, возвращая объект Path который можно использовать для поиска и доступа к файлу.

  • Метод getPathMatcher используется для создания PathMatcher который выполняет операции сопоставления на путях.

  • Метод getFileStores возвращает итератор для базовых файловых хранилищ.

  • Метод getUserPrincipalLookupService возвращает UserPrincipalLookupService для поиска пользователей или групп по имени.

  • Метод newWatchService создает WatchService который можно использовать для отслеживания объектов на предмет изменений и событий.

И еще есть интерфейс Path :

Объект, который может быть использован для поиска файла в файловой системе. Обычно он представляет системно-зависимый путь к файлу.

Обратите внимание, что Path - это просто путь. Он не обязательно представляет реальный файл, только путь к файлу (существует он или нет). Это похоже на java.io.File в этом отношении.

Когда вы вызываете методы в классе Files он использует методы Path#getFileSystem() и FileSystem#provider() для делегирования FileSystemProvider . Этот дизайн API позволяет разработчику прозрачно использовать класс Files с любой реализацией Path . Для разработчика не имеет значения, как создается этот InputStream , только то, что InputStream создается способом, соответствующим контрактам API.

Методы Paths#get(String,String...) и Path#of(String,String...) делегируют файловой системе по умолчанию для создания экземпляра Path . Когда вы используете эти экземпляры Path с методами в Files вы получаете доступ к основной файловой системе платформы хоста.

Если вы хотите создать виртуальную файловую систему, вам нужно реализовать FileSystemProvider вместе со всеми связанными абстрактными классами и интерфейсами, такими как FileSystem и Path . Хотя обратите внимание, что некоторые API являются «необязательными». Если ваша реализация не предоставляет необязательный API, вы можете выбросить UnsupportedOperationException . Javadoc различных классов / методов дает больше информации.

Тем не менее, уже есть реализация файловой системы в памяти: https://github.com/google/jimfs


« Но мне неясно, как это можно сделать без создания экземпляра файла (InputStream) ». Файловый API NIO не связан с java.io.File . Если вы хотите увидеть, как он делает то, что он делает, вы можете посмотреть на исходный код. Ваш JDK должен был прийти с файлом src.zip который содержит исходные файлы Java; однако он будет содержать только реализацию для вашей операционной системы хоста и не будет содержать никакого собственного кода (файловые системы по умолчанию в конечном итоге используют собственный код для связи с файловой системой базовой ОС).


Есть идеи?

10000