Я сейчас полностью запутался - в основном из-за терминологии, наверное. Может ли кто-нибудь рассказать мне о различиях или дать несколько ссылок на материалы, защищающие от пустышек? Особенно URI для URL и Resource to File? Мне кажется, что они должны быть одинаковыми, соответственно ...
Терминология сбивает с толку и иногда сбивает с толку, и в основном она родилась в результате эволюции Java как API и как платформы с течением времени. Чтобы понять, как эти термины стали означать то, что они делают, важно признать две вещи, которые влияют на дизайн Java:
- Обратная совместимость. Старые приложения должны работать на новых установках, в идеале без изменений. Это означает, что старый API (с его названиями и терминологией) необходимо поддерживать во всех новых версиях.
- Кроссплатформенность. API должен предоставлять удобную абстракцию своей базовой платформы, будь то операционная система или браузер.
Я расскажу о концепциях и о том, как они появились. После этого я отвечу на другие ваши, конкретные вопросы, потому что, возможно, мне придется упомянуть кое-что в первой части.
Что такое «ресурс»?
Абстрактный общий фрагмент данных, который можно найти и прочитать. Грубо говоря, Java использует это для обозначения «файла», который может не быть файлом, но представляет именованный фрагмент данных. Он не имеет прямого представления класса или интерфейса в Java , но из-за своих свойств (доступный для поиска, читаемый) он часто представляется URL-адресом.
Поскольку одна из первых целей разработки Java заключалась в том, чтобы запускаться внутри браузера, как изолированное приложение (апплеты!) С очень ограниченными правами / привилегиями / уровнем безопасности, Java делает четкую (теоретическую) разницу между файлом (чем-то на локальном компьютере). файловая система) и ресурс (то, что ему нужно прочитать). Вот почему чтение чего-либо, относящегося к приложению (значки, файлы классов и т. Д.), Выполняется через, ClassLoader.getResource
а не через класс File.
К сожалению, поскольку «ресурс» также является полезным общим термином вне этой интерпретации, он также используется для обозначения очень конкретных вещей (например, класса ResourceBundle , UIResource , Resource ), которые в этом смысле не являются ресурсом.
Основными классами, представляющими (путь к) ресурсу, являются java.nio.file.Path , java.io.File , java.net.URI и java.net.URL .
Файл (java.io, 1.0)
Абстрактное представление путей к файлам и каталогам.
Класс File представляет ресурс, доступный через собственную файловую систему платформы . Он содержит только имя файла, поэтому на самом деле это скорее путь (см. Ниже), который платформа хоста интерпретирует в соответствии со своими собственными настройками, правилами и синтаксисом.
Обратите внимание, что File не должен указывать на что-то локальное , просто на то, что хост-платформа понимает в контексте доступа к файлу, например, путь UNC в Windows. Если вы смонтируете ZIP-файл в качестве файловой системы в своей ОС, тогда File будет нормально читать содержащиеся в нем записи.
URL (java.net, 1.0)
URL-адрес класса представляет собой унифицированный указатель ресурса, указатель на «ресурс» во всемирной паутине. Ресурс может быть чем-то таким же простым, как файл или каталог, или может быть ссылкой на более сложный объект, например запрос к базе данных или поисковой системе.
В тандеме с концепцией ресурса URL-адрес представляет этот ресурс так же, как класс File представляет файл на платформе хоста: как структурированная строка, указывающая на ресурс. URL дополнительно содержит схему, которая намекает на то, как добраться до ресурса (где «file:» означает «запросить платформу хоста»), и поэтому позволяет указывать на ресурсы через HTTP, FTP, внутри JAR и так далее.
К сожалению, URL-адреса имеют собственный синтаксис и терминологию, включая использование «файла» и «пути». В случае, если URL-адрес является URL-адресом файла, URL.getFile вернет строку, идентичную строке пути указанного файла.
Class.getResource
возвращает URL: он более гибкий, чем возврат File, и удовлетворяет потребности системы, как это предполагалось в начале 1990-х годов.
URI (java.net, 1.4)
Представляет ссылку на универсальный идентификатор ресурса (URI).
URI - это (небольшая) абстракция по URL-адресу. Разница между URI и URL-адресом является концептуальной и в основном академической, но URI лучше определяется в формальном смысле и охватывает более широкий спектр вариантов использования. Поскольку URL и URI - это не одно и то же, для их представления был представлен новый класс с методами URI.toURL и URL.toURI для перемещения между одним и другим.
В Java основное различие между URL-адресом и URI заключается в том, что URL-адрес несет ожидание разрешения , от чего приложению может потребоваться InputStream; URI рассматривается больше как абстрактная вещь, которая может указывать на что-то разрешимое (и обычно так и есть), но то, что он означает, и способы его достижения более открыты для контекста и интерпретации.
Путь (java.nio.file, 1.7)
Объект, который может использоваться для поиска файла в файловой системе. Обычно он представляет собой системно-зависимый путь к файлу.
Новый файловый API, обозначенный иконкой в интерфейсе Path, обеспечивает гораздо большую гибкость, чем может предложить класс File. Интерфейс Path является абстракцией класса File и является частью New IO File API . Если File обязательно указывает на «файл» в понимании хост-платформы, Path является более общим: он представляет файл (ресурс) в произвольной файловой системе.
Путь устраняет зависимость от концепции файла на платформе хоста. Это может быть запись в ZIP-файле, файл, доступный через FTP или SSH-FS, представление пути к классам приложения с несколькими корнями или что угодно, что может быть осмысленно представлено через интерфейс FileSystem и его драйвер FileSystemProvider. Он дает возможность «монтировать» файловые системы в контексте приложения Java.
Платформа хоста представлена через «файловую систему по умолчанию»; при вызове File.toPath
вы получаете Path в файловой системе по умолчанию.
Теперь, если у меня есть локатор, который ссылается на класс или пакет в файле jar, будут ли эти два (т.е. путь к строкам файла) отличаться?
Вряд ли. Если файл банка находится на локальной файловой системе, вы не должны иметь компонент запроса, так URL.getPath
и URL.getFile
должен возвращать один и тот же результат. Однако выберите тот, который вам нужен: URL-адреса файлов обычно могут не иметь компонентов запроса, но я все равно мог бы добавить их.
Наконец - и самое главное - зачем мне нужен объект File; почему недостаточно ресурса (URL)?
URL-адреса может быть недостаточно, потому что File дает вам доступ к служебным данным, таким как разрешения (для чтения, записи, исполняемого файла), тип файла (я каталог?) И возможность поиска и управления локальной файловой системой. Если эти функции вам нужны, их предоставят Файл или Путь.
Вам не нужен файл, если у вас есть доступ к пути. Однако для некоторых старых API может потребоваться File.
(А есть ли объект ресурса?)
Нет, нет. Таких названий много, но они не являются ресурсом в смысле ClassLoader.getResource
.
Path