Как Java Путь преобразуется, например, в InputStream - PullRequest
1 голос
/ 10 февраля 2020

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

1 Ответ

3 голосов
/ 10 февраля 2020

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 interface:

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

Обратите внимание, что 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. Javado c различных классов / методов дает больше информации.

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


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

...