Jaka jest różnica między zasobem, URI, adresem URL, ścieżką i plikiem w Javie?

Patrzę teraz na fragment kodu Javy, który pobiera ścieżkę jako ciąg znaków i pobiera swój adres URL za pomocą URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);, następnie wywołuje String path = resource.getPath() i w końcu wykonuje new File(path);.

Są też połączenia do URL url = resource.toURI(); i String file = resource.getFile().

Jestem teraz całkowicie zdezorientowany-głównie z powodu terminologii, tak myślę. Czy ktoś mógłby mi opowiedzieć o różnicach, albo podać kilka linków do materiałów odpornych na atrapy? Szczególnie URI do URL i zasób do pliku? Dla mnie to wydaje się, że powinny być odpowiednio tym samym...

Różnica między getFile() oraz getPath() jest wyjaśnione tutaj: Jaka jest różnica między url.getFile () i getpath ()? (co ciekawe, obie wydają się zwracać struny, co prawdopodobnie dodaje wiele do mojego stanu umysłu...)

Teraz, jeśli mam lokalizator, który odwołuje się do klasy lub pakietu w pliku jar, czy te dwa (tzn. ścieżka do pliku) będą się różnić?

resource.toString() dałby ty jar:file:/C:/path/to/my.jar!/com/example/, W końcu (zwróć uwagę na wykrzyknik).

Jest różnicą pomiędzy URI i URL w Javie że ten pierwszy nie koduje spacji? Cf. pliki, Uri i adresy URL sprzeczne w Javie (Ta odpowiedź wyjaśnia ogólną, koncepcyjną różnicę między tymi dwoma pojęciami dość dobrze: Uri identyfikują i lokalizują adresy URL;)

Na koniec-i co najważniejsze- Dlaczego potrzebuję File obiektu; dlaczego nie jest zasobem (URL) wystarczy? (a czy istnieje obiekt Resource?)

Przepraszam, jeśli to pytanie jest trochę niezorganizowane; to po prostu odzwierciedla zamieszanie mam... :)

Author: Community, 2015-01-08

5 answers

Aktualizacja 2017-04-12 Sprawdź odpowiedź JvR ponieważ zawiera bardziej wyczerpujące i dokładne wyjaśnienie!


Proszę zauważyć, że nie uważam się w 100% za kompetentnego, aby odpowiedzieć, ale mimo to oto kilka komentarzy:

  • File reprezentuje plik lub katalog dostępny przez system plików
  • resource jest terminem ogólnym dla obiektu danych, który może być ładowany przez aplikację
    • Zwykle [2]}zasoby są plikami dystrybuowanymi wraz z aplikacją / biblioteką i ładowanymi za pomocą mechanizmu ładowania klas (gdy znajdują się na ścieżce klasy)
  • URL#getPath jest getter w ścieżce URL (protocol://host/path?query)
  • URL#getFile zgodnie z Javadoc zwraca path+query

W języku Java, URI jest tylko strukturą danych służącą do manipulowania ogólnym identyfikatorem.

URL z drugiej strony jest naprawdę lokalizator zasobów i oferuje funkcje, aby rzeczywiście przeczytać zasób via registered URLStreamHandler s.

Adresy URL mogą prowadzić do zasobów systemu plików i można konstruować adresy URL dla każdego zasobu systemu plików za pomocą protokołu file:// (stąd File URL relacja).

Należy również pamiętać, że to URL#getFile jest niezwiązane z java.io.File.


Dlaczego potrzebuję obiektu File; dlaczego zasób (URL) nie jest wystarczający?

Wystarczy. Tylko jeśli chcesz przekazać zasób do jakiegoś komponentu, który może pracować tylko z plikami, musisz uzyskać File z to. Jednak nie wszystkie adresy URL zasobów mogą być konwertowane na File s.

A czy istnieje obiekt Resource?

Z punktu widzenia JRE, to tylko określenie. Niektóre frameworki zapewniają taką klasę(np. źródło Springa).
 43
Author: Pavel Horal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:26:36

Jestem teraz całkowicie zdezorientowany-głównie z powodu terminologii, tak myślę. Czy ktoś mógłby mi opowiedzieć o różnicach, albo podać kilka linków do materiałów odpornych na atrapy? Zwłaszcza URI do adresu URL i zasobu do pliku? Dla mnie, wydaje mi się, że powinny one być odpowiednio tym samym...

[7]}terminologia jest myląca i czasami oszałamiająca, a wynika głównie z ewolucji zarówno Javy jako API, jak i platformy w czasie. Aby zrozumieć, w jaki sposób powstały te warunki jeśli chodzi o to, co robią, ważne jest, aby rozpoznać dwie rzeczy, które mają wpływ na projektowanie Javy:]}
  • zgodność wsteczna. stare aplikacje powinny działać na nowszych instalacjach, najlepiej bez modyfikacji. Oznacza to, że stare API (wraz z jego nazwami i terminologią) musi być utrzymywane we wszystkich nowszych wersjach.
  • Cross-platform.[15]} API powinno zapewniać użyteczną abstrakcję swojej podstawowej platformy, niezależnie od tego, czy jest to system operacyjny, czy przeglądarka.
Przejdę przez koncepcje i sposób, w jaki powstały. Odpowiem na inne, konkretne pytania, bo być może będę musiał odnieść się do czegoś w pierwszej części.

Co to jest "zasób"?

Abstrakcyjny, ogólny fragment danych, który można zlokalizować i odczytać. luźno mówiąc, Java używa tego określenia do odniesienia się do" pliku", który może nie być plikiem, ale reprezentuje określony fragment danych. nie ma bezpośredniej klasy ani interfejsu reprezentacja w Javie , ale ze względu na swoje właściwości (lokalizowalne, czytelne) jest często reprezentowana przez adres URL.

Ponieważ jednym z wczesnych celów projektowych Javy było uruchamianie wewnątrz przeglądarki, jako aplikacji w piaskownicy (aplety! dzięki bardzo ograniczonym uprawnieniom/uprawnieniom/poświadczeniom bezpieczeństwa, Java tworzy wyraźną (teoretyczną) różnicę między plikiem (czymś w lokalnym systemie plików) a zasobem (czymś, co musi przeczytać). dlatego czytając coś w stosunku do aplikacja (ikony, pliki klas itd.) odbywa się przez ClassLoader.getResource, a nie przez klasę plików.

Niestety, ponieważ "zasób" jest również użytecznym terminem ogólnym poza tej interpretacji, używa się go również do nazwania bardzo konkretnych rzeczy (np. Klasa ResourceBundle, UIResource, Resource ), które nie są w tym sensie zasobem.

Główne klasy reprezentujące (ścieżkę do) zasobu to java.nio.plik.Ścieżka , plik java. io., java. net. URI oraz java. net. URL .

Plik (java.io, 1, 0)

Abstrakcyjna reprezentacja nazw plików i katalogów.

Klasa plików reprezentuje zasób, który jest osiągalny przez natywny system plików platformy. Zawiera tylko nazwę pliku, więc jest to bardziej ścieżka (zobacz później), którą Platforma hosta interpretuje zgodnie z własnymi ustawieniami, regułami i składnia.

Zauważ, że plik nie musi wskazywać na coś lokalnego , tylko coś, co Platforma hosta rozumie w kontekście dostępu do pliku, np. ścieżkę UNC w systemie Windows. Jeśli zamontujesz plik ZIP jako system plików w systemie operacyjnym, plik będzie dobrze odczytywał zawarte w nim wpisy.

URL (java.net, 1, 0)

Class URL reprezentuje Uniform Resource Locator, wskaźnik do "zasobu" w sieci World Wide Web. Zasób może być czymś tak prostym jako plik lub katalog, lub może to być odniesienie do bardziej skomplikowanego obiektu, takiego jak zapytanie do bazy danych lub Wyszukiwarki.

W powiązaniu z pojęciem zasobu, adres URL reprezentuje ten zasób w taki sam sposób, w jaki Klasa pliku reprezentuje plik na platformie hosta: jako uporządkowany łańcuch znaków, który wskazuje na zasób. URL dodatkowo zawiera schemat, który podpowiada, jak dotrzeć do zasobu (z "file:" jest "zapytaj platformę hosta"), a więc pozwala wskazywanie zasobów przez HTTP, FTP, wewnątrz słoika i tak dalej.

Niestety, adresy URL mają własną składnię i terminologię, w tym użycie "file" I "path". W przypadku, gdy adres URL jest plikiem-URL, URL.getFile zwróci ciąg znaków identyczny z ciągiem ścieżek pliku odniesienia.

Class.getResource zwraca adres URL: jest bardziej elastyczny niż zwracany plik i służył potrzebom systemu zgodnie z wyobrażeniami z wczesnych lat 90.]}

URI (java.net, 1.4)

Reprezentuje odniesienie do Uniform Resource Identifier (URI).

URI to (niewielka) abstrakcja nad adresem URL. różnica między URI i URL jest pojęciowa i głównie akademicka, ale URI jest lepiej zdefiniowany w sensie formalnym i obejmuje szerszy zakres przypadków użycia. Ponieważ URL i URI to nie to samo, wprowadzono nową klasę do ich reprezentowania, z metodami URI.toURL i URL.toURI, aby poruszać się między jednym a drugim.

W Javie głównym różnica między URL i URI polega na tym, że URL niesie ze sobą oczekiwanie, że będzie możliwy do rozwiązania , coś, z czego aplikacja może chcieć strumienia wejściowego; URI jest traktowany bardziej jak abstrakcyjna rzecz, która może {38]} wskazywać na coś możliwego do rozwiązania (i zazwyczaj to robi), ale co to oznacza i jak do niego dotrzeć są bardziej otwarte na kontekst i interpretację.

Path (java.nio.plik, 1.7)

Obiekt, który może być użyty do zlokalizowania pliku w systemie plików. Zazwyczaj reprezentuje ścieżkę pliku zależną od systemu.

Nowe API plików, ikonowane w interfejsie ścieżki, pozwala na znacznie większą elastyczność niż klasa plików może zaoferować. Interfejs ścieżki jest abstrakcją Klasy plików i jest częścią New Io File API . Jeśli plik wskazuje na "plik" w rozumieniu platformy hosta, ścieżka jest bardziej ogólna: reprezentuje plik (zasób) w arbitralnym pliku system.

Ścieżka usuwa zależność od koncepcji pliku platformy hosta. Może to być wpis w pliku ZIP, plik dostępny przez FTP lub SSH-FS, wielo-zakorzeniona reprezentacja ścieżki klasowej aplikacji, lub naprawdę wszystko, co może być znacząco reprezentowane przez interfejs systemu plików i jego sterownik, FileSystemProvider. Przenosi moc "montowania" systemów plików w kontekst aplikacji Java.

Platforma hosta jest reprezentowana przez "domyślny system plików"; gdy wywołujesz File.toPath, otrzymasz ścieżkę do domyślnego systemu plików.


Teraz, jeśli mam lokalizator, który odwołuje się do klasy lub pakietu w pliku jar, czy te dwa (tzn. ścieżka do pliku) będą się różnić?

Mało prawdopodobne. Jeśli plik jar znajduje się w lokalnym systemie plików, nie powinieneś mieć komponentu zapytania, więc URL.getPath i URL.getFile powinny zwrócić ten sam wynik. Wybierz jednak ten, którego potrzebujesz: file-url może zazwyczaj nie mieć komponentów zapytań, ale mogę pewnie i tak dodasz.

Na koniec-i co najważniejsze-po co mi obiekt File; dlaczego nie wystarcza zasób (URL)?

URL może nie wystarczyć, ponieważ plik daje dostęp do danych porządkowych, takich jak uprawnienia (czytelne, zapisywalne, wykonywalne), Typ pliku (Czy jestem katalogiem?), oraz możliwość przeszukiwania i manipulowania lokalnym systemem plików. Jeśli są to funkcje, których potrzebujesz, podaj je plik lub ścieżka.

Nie potrzebujesz Pliku, jeśli masz dostęp do ścieżki. Niektóre starsze API mogą jednak wymagać pliku.

(a czy istnieje obiekt Resource?)

Nie, Nie ma. Jest wiele rzeczy o podobnych nazwach, ale nie są one zasobem w sensie ClassLoader.getResource.

 57
Author: JvR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-06-20 09:12:55

Odpowiedź Pavel Horal jest ładna.

Jak mówi, słowo "plik" ma zupełnie inne (praktycznie niepowiązane) znaczenia w URL#getFile vs java.io.File - może to część zamieszania .

Aby dodać:

  • Zasoby w Javie są abstrakcyjnym pojęciem, źródłem danych, które można odczytać. Lokalizacja (lub adres) zasobu jest reprezentowana w Javie przez URL obiekt.

  • A resource can odpowiada zwykłemu plikowi w lokalnym systemie plików(konkretnie, gdy jego URL zaczyna się od file://). Ale zasób jest bardziej ogólny (może to być również jakiś plik przechowywany w jar, lub niektóre dane do odczytu z sieci, lub z pamięci, lub. ..). Jest to również bardziej ograniczone, ponieważ File (poza tym, że jest czymś innym niż zwykły plik: katalogiem, linkiem) można również tworzyć i zapisywać do.

  • Zapamiętaj w Javie a File obiekt tak naprawdę nie reprezentuje " pliku" ale lokalizacja (pełna nazwa, ze ścieżką) pliku. Tak więc obiekt File pozwala zlokalizować (i otworzyć) plik, tak jak obiekt URL pozwala uzyskać dostęp (i otworzyć) do zasobu. (Nie ma Resource klasy w Javie, która reprezentowałaby zasób, ale nie ma takiej, która reprezentowałaby plik! jeszcze raz: File to nie Plik, to ścieżka do pliku).

 12
Author: leonbloy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:45

Jak je Rozumiem, można je podzielić na następujące kategorie:

Web-Based: Uri i Url.

  • URL: adres URL to określona lokalizacja na internt (zwykły webaddress jak - stackoverflow.com)
  • Uri: ever URL is an URI. Ale Uri mogą również zawierać rzeczy takie jak " mailto:", więc są one również, cóż, co z "skryptu" powiedziałbym.

Oraz local: Resource, Path and Files

  • Resource: Resources are files in your jar. Stosowane są aby załadować pliki ze słoików / pojemników.
  • Ścieżka: Ścieżka jest w zasadzie ciągiem znaków. Ale jest wyposażony w kilka przydatnych funkcji do łączenia wielu ciągów lub dodawania plików do ciągu. Zapewnia, że ścieżka, którą budujesz, jest prawidłowa.
  • plik: jest to odniesienie do katalogu lub pliku. Służy do modyfikowania plików, otwierania ich itp.

Byłoby łatwiej, gdyby połączyły się w jedną klasę - są naprawdę mylące: d

Mam nadzieję, że to ci pomoże:)

(I just zapoznałem się z dokumentacją-zajrzyj do docs.oracle.com)

 3
Author: Cyphrags,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 17:02:08

Plik jest abstrakcyjną reprezentacją encji w lokalnym systemie plików.

Ścieżka jest zazwyczaj łańcuchem znaków wskazującym lokalizację pliku w systemie plików. Zazwyczaj nie zawiera nazwy pliku. Więc c:\documents\mystuff\stuff.txt będzie miał ścieżkę o wartości "C:\documents\mystuff" oczywiście format bezwzględnych nazw plików i ścieżek różniłby się znacznie w zależności od systemu plików.

URL to susbset URI z adresem URL reprezentującym Zwykle zasoby dostępne przez http. Nie sądzę, że istnieje jakaś żelazna zasada, kiedy coś musi być URI vs URL. URI to ciągi znaków w postaci "protocol: / / resource-identifier", takich jak bitcoin: / / params, http://something.com?param=value . klasy takie jak URL zazwyczaj zawijają łańcuch znaków i dostarczają metod użytkowych, których łańcuch nie miałby powodu podawać.

Nie ma czegoś takiego jak zasoby, przynajmniej nie w tym sensie, o którym mówisz. Tylko dlatego, że metoda nazywa się getResource nie oznacza to, że zwraca obiekt typu Resource.

Ostatecznie najlepszym sposobem, aby dowiedzieć się, co robią metody klasy, jest utworzenie jej instancji w kodzie, wywołanie metod, a następnie Przejście W trybie debugowania lub wysłanie wyników do systemu.Wynocha.

 0
Author: Jim W,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-08 17:08:49