Какая разница между ресурсом, URI, URL, контуром и файлом на Java?

Я смотрю на кусок кода Java прямо сейчас, и он берет путь как String и получает свой URL-адрес с помощью URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);, затем вызывает String path = resource.getPath() и, наконец, выполняет new File(path);.

О, и есть также вызовы URL url = resource.toURI(); и String file = resource.getFile().

Я сейчас полностью запутался - в основном из-за терминологии, я думаю. Может кто-нибудь, пожалуйста, проведет меня через различия или предоставит несколько ссылок на материал, защищенный от манекенов? Особенно URI для URL и ресурса для файла? Мне кажется, что они должны быть одинаковыми, соответственно...

Здесь объясняется разница между getFile() и getPath(): Какая разница между url.getFile() и getpath()? (Интересно, что оба они, похоже, возвращают Strings, что, вероятно, добавляет много моего душевного состояния...)

Теперь, если у меня есть локатор, который ссылается на класс или пакет в файле jar, будут ли эти два (т.е. путь к файлам) отличаться?

resource.toString() даст вам jar:file:/C:/path/to/my.jar!/com/example/, в конце концов (отметьте восклицательный знак).

Является ли разница между URI и URL на Java, что первая не кодирует пробелы? Ср Файлы, URI и URL-адреса, конфликтующие с Java (Этот ответ объясняет общую концептуальную разницу между двумя терминами довольно хорошо: URI определить и найти URL-адреса;)

Наконец - и самое главное - зачем мне нужен объект File; почему не является ресурсом (URL) достаточно? (И есть ли объект Resource?)

Извините, если этот вопрос немного неорганизован; это просто отражает путаницу, которую я имею...:)

Ответ 1

ОБНОВЛЕНИЕ 2017-04-12 Отметьте ответ JvR, поскольку он содержит более исчерпывающее и точное объяснение!


Обратите внимание, что я не считаю себя 100% компетентным отвечать, но, тем не менее, есть несколько комментариев:

  • File представляет файл или каталог, доступные через файловую систему
  • ресурс общий термин для объекта данных, который может быть загружен приложением
    • Обычно ресурсы - это файлы, распространяемые с помощью приложения/библиотеки и загружаемые через механизм загрузки классов (когда они находятся на пути к классу)
  • URL#getPath - getter на пути к URL-адресу (protocol://host/path?query)
  • URL#getFile в соответствии с JavaDoc возвращает path+query

В Java URI - это просто структура данных для управления самим идентификатором.

URL, с другой стороны, действительно является локатором ресурсов и предлагает вам функции для фактического чтения ресурса через зарегистрированные URLStreamHandler s.

URL-адреса могут приводить к ресурсам файловой системы, и вы можете создать URL-адрес для каждого ресурса файловой системы, используя протокол file:// (следовательно, отношение FileURL).

Также имейте в виду, что URL#getFile не имеет отношения к java.io.File.


Зачем нужен объект File; почему недостаточно ресурсов (URL)?

Этого достаточно. Только если вы хотите передать ресурс некоторому компоненту, который может работать только с файлами, вам нужно получить File от него. Однако не все URL-адреса ресурсов могут быть преобразованы в File s.

И есть ли объект ресурса?

С точки зрения JRE это просто термин. Некоторые структуры предоставляют вам такой класс (например, Spring Resource).

Ответ 2

Я сейчас полностью запутался - в основном из-за терминологии, я думаю. Может кто-нибудь, пожалуйста, проведет меня через различия или предоставит несколько ссылок на материал, защищенный от манекенов? Особенно URI для URL и ресурса для файла? Мне кажется, что они должны быть одинаковыми, соответственно...

Терминология сбивает с толку, а иногда и путается, и в основном рождается из эволюции как Java, так и API и как платформы с течением времени. Чтобы понять, как эти термины стали означать, что они делают, важно признать две вещи, которые влияют на дизайн Java:

  • Обратная совместимость. Старые приложения должны работать на более новых установках, в идеале без изменений. Это означает, что старый API (с его именами и терминологией) должен поддерживаться всеми новыми версиями.
  • Кросс-платформенный.. API должен обеспечивать полезную абстракцию базовой платформы, будь то операционная система или браузер.

Я пройду через концепции и то, как они стали. Я отвечу на ваши другие, конкретные вопросы после этого, потому что мне, возможно, придется обратиться к чему-то в первой части.

Что такое "Ресурс"?

Абстрактный, общий фрагмент данных, который может быть расположен и прочитан.. Говоря кратко, Java использует это, чтобы ссылаться на "файл", который не может быть файлом, но представляет собой именованный фрагмент данные. Он не имеет прямого представления класса или интерфейса в Java, но из-за его свойств (локализуемых, читаемых) он часто представлен URL-адресом.

Поскольку одна из ранних целей разработки Java была запущена внутри браузера, в качестве изолированного приложения (апплеты!) с очень ограниченными правами/привилегиями/безопасностью, Java дает четкую (теоретическую) разницу между файл (что-то в локальной файловой системе) и ресурс (что-то нужно прочитать). Вот почему чтение чего-то относительно приложения (значков, файлов классов и т.д.) осуществляется через ClassLoader.getResource и а не через класс File.

К сожалению, поскольку "ресурс" также является полезным универсальным термином вне этой интерпретации, он также используется для обозначения очень специфических вещей (например, class ResourceBundle, UIResource, Resource), которые в этом смысле не являются ресурсом.

Основные классы, представляющие (путь к) ресурсу, java.nio.file.Path, java.io.File, java.net.URI и java.net.URL.

File (java.io, 1.0)

Абстрактное представление имен файлов и каталогов.

Класс File представляет ресурс, который доступен через собственную файловую систему платформы. Он содержит только имя файла, так что это действительно больше путь (см. Ниже), который платформа хоста интерпретирует в соответствии с его собственными настройками, правилами и синтаксисом.

Обратите внимание, что File не нужно указывать на что-то локальное, только то, что платформа хоста понимает в контексте доступа к файлу, например. UNC-путь в Windows. Если вы монтируете ZIP файл в качестве файловой системы в своей ОС, тогда файл будет читать его содержащиеся записи просто отлично.

URL (java.net, 1.0)

URL-адрес класса представляет собой унифицированный указатель ресурса, указатель на "ресурс" в World Wide Web. Ресурс может быть таким же простым, как файл или каталог, или может быть ссылкой на более сложный объект, такой как запрос к базе данных или поисковой системе.

В сочетании с концепцией ресурса URL-адрес представляет этот ресурс таким же образом, как класс File представляет файл на платформе хоста: структурированная строка, указывающая на ресурс. URL дополнительно содержит схему, которая подсказывает, как достичь ресурса (с "файлом": "запрашивать платформу хоста" ), и поэтому позволяет указывать ресурсы через HTTP, FTP, внутри JAR и еще что-то.

К сожалению, URL-адреса имеют свой собственный синтаксис и терминологию, включая использование "файла" и "пути". Если URL-адрес является URL-адресом файла, URL.getFile вернет строку, идентичную строке пути ссылочного файла.

Class.getResource возвращает URL-адрес: он более гибкий, чем возвращаемый файл, и он удовлетворяет потребности системы, как предполагалось в начале 1990-х годов.

URI (java.net, 1.4)

Представляет ссылку на унифицированный идентификатор ресурса (URI).

URI - это (небольшая) абстракция по URL-адресу. Разница между URI и URL является концептуальной и в основном академической, но URI лучше определяется в формальном смысле и охватывает более широкий спектр вариантов использования, Поскольку URL и URI являются/не то же самое, для представления их был введен новый класс, с методами URI.toURL и URL.toURI для перемещения между ними.

В Java основное различие между URL и URI заключается в том, что URL-адрес несет ожидание разрешения, от приложения, от которого может потребоваться InputStream; URI рассматривается скорее как абстрактный объект, который может указывать на что-то разрешимое (и обычно это делает), но то, что оно означает и как его достичь, более открыто для контекста и интерпретации.

Path (java.nio.file, 1.7)

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

Новый API файлов, обозначенный в интерфейсе Path, обеспечивает гораздо большую гибкость, чем может предложить класс File. Интерфейс Path является абстракцией класса File и является частью нового API файлов IO. Если файл обязательно указывает на "файл", понятный платформе хоста, путь более общий: он представляет файл (ресурс) в произвольной файловой системе.

Путь устраняет зависимость концепции платформы хоста от файла. Это может быть запись в ZIP файл, файл, доступный через FTP или SSH-FS, многокорпусное представление пути к классу приложений или, действительно, все, что может быть осмысленно представлено через интерфейс FileSystem и его драйвер FileSystemProvider. Он привносит силу "монтирования" файловых систем в контекст приложения Java.

Платформа хоста представлена ​​через "файловую систему по умолчанию"; когда вы вызываете File.toPath, вы получаете Путь в файловой системе по умолчанию.


Теперь, если у меня есть локатор, который ссылается на класс или пакет в файле jar, будут ли эти два (т.е. путь к файлам) отличаться?

Вряд ли. Если файл jar находится в локальной файловой системе, у вас не должно быть компонента запроса, поэтому URL.getPath и URL.getFile должны возвращать тот же результат. Однако выберите тот, который вам нужен: у файлов-URL обычно нет компонентов запроса, но я все равно мог бы добавить их.

Наконец - и самое главное - зачем мне нужен объект File; почему недостаточно ресурсов (URL)?

URL-адрес может быть недостаточным, потому что File дает вам доступ к служебным данным, таким как разрешения (читаемые, записываемые, исполняемые), тип файла (am я a directory?) и возможность поиска и управления локальной файловой системой. Если эти функции вам нужны, тогда File или Path предоставят их.

Вам не нужен файл, если у вас есть доступ к Path. Однако для некоторых старых API может потребоваться файл.

(И есть ли объект Resource?)

Нет, нет. Есть много названных им вещей, но они не являются ресурсом в смысле ClassLoader.getResource.

Ответ 3

Павел Хорал отвечает.

Как он говорит, слово "файл" имеет совершенно разные (практически несвязанные) значения в URL#getFile vs java.io.File - может быть той частью путаницы.

Просто добавьте:

  • A ресурс в Java - это абстрактное понятие, источник данных, который можно прочитать. Местоположение (или адрес) ресурса представлено в Java объектом URL.

  • A ресурс может соответствовать регулярному файлу в локальной файловой системе (в частности, когда его URL начинается с file://). Но ресурс более общий (это может быть и некоторый файл, хранящийся в банке, или некоторые данные, которые нужно читать из сети, или из памяти, или...). И это также более ограничено, потому что File (помимо других вещей, чем обычный файл: каталог, ссылка) также может быть создан и написан на.

  • Помните, что в Java объект File не представляет собой "файл", а местоположение (полное имя, путь) файла. Таким образом, объект File позволяет вам находить (и открывать) файл, так как URL позволяет вам получить доступ (и открыть) ресурс. (В Java нет класса Resource для представления ресурса, но не существует одного для представления файла! Еще раз: File не является файлом, это путь к файлу).

Ответ 4

Как я понимаю, вы можете классифицировать их следующим образом:

Веб-интерфейс: URI и URL-адреса.

  • URL-адреса: URL-адрес - это определенное место в интернете (только обычный веб-адрес, например - stackoverflow.com).
  • URI: Ever URL - это URI. Но URI также могут содержать такие вещи, как "mailto:", поэтому они также хорошо знают, что из "script" я бы сказал.

И локальный: ресурс, путь и файлы

  • Ресурс: ресурсы - это файлы внутри вашей банки. Они используются для загрузки файлов из контейнеров/контейнеров.
  • Путь: путь - это в основном строка. Но он поставляется с некоторыми удобными функциями для конкатенации нескольких строк или добавления файлов в строку. Это гарантирует, что путь, который вы строите, действителен.
  • Файл: это ссылка на каталог или файл. Он используется для изменения файлов, их открытия и т.д.

Было бы проще, если бы они были объединены в один класс - они действительно запутывают: D

Надеюсь, это поможет вам:)

(Я просто посмотрел документацию - посмотрите на docs.oracle.com)

Ответ 5

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

Путь - это обычно строка, указывающая расположение файла в файловой системе. Обычно он не включает имя файла. Таким образом, c:\documents\mystuff\stuff.txt имеет путь со значением "C:\documents\mystuff". Очевидно, что формат абсолютных имен файлов и путей будет сильно отличаться от файловой системы к файловой системе.

URL-адрес является подозрительным для URI с URL-адресом, обычно представляющим ресурсы, доступные через http. Я не думаю, что существует какое-то чудовищное правило, когда что-то должно быть URI и URL. URI представляют собой строки в виде "protocol://resource-identifier", такие как bitcoin://params, http://something.com?param=value. Классы, такие как URL, как правило, обертывают строку и предоставляют утилиты, которые String не имеет причин для поставки.

Нет такой вещи, как Ресурс, по крайней мере, не в том смысле, о котором вы говорите. Просто потому, что метод называется getResource, не означает, что он возвращает объект типа Resource.

В конечном итоге лучший способ выяснить, что делают методы класса, - создать экземпляр этого кода, вызвать методы, а затем либо выполнить переход в режиме отладки, либо отправить результаты в System.out.