Frage Was ist der Unterschied zwischen einer Ressource, URI, URL, Pfad und Datei in Java?


Ich schaue gerade ein Stück Java-Code an, und es nimmt einen Pfad als String und erhält seine URL mit URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);, dann ruft an String path = resource.getPath() und führt schließlich aus new File(path);.

Oh, und es gibt auch Anrufe zu URL url = resource.toURI(); und String file = resource.getFile().

Ich bin gerade total verwirrt - hauptsächlich wegen der Terminologie, denke ich. Kann mir bitte jemand die Unterschiede erklären oder ein paar Links zu dummy-sicherem Material geben? Vor allem URI zu URL und Ressource zu Datei? Für mich fühlt es sich an, als ob sie das gleiche sein sollten ...

Der Unterschied zwischen getFile() und getPath() wird hier erklärt: Was ist der Unterschied zwischen url.getFile () und getpath ()? (Interessanterweise scheinen beide Strings zurückzugeben, was meiner Gemütsverfassung wahrscheinlich eine ganze Menge hinzufügt ...)

Wenn ich jetzt einen Locator habe, der auf eine Klasse oder ein Paket in einer JAR-Datei verweist, werden sich diese beiden (d. H. Pfadangaben für eine Datei) unterscheiden?

resource.toString() würde dir geben jar:file:/C:/path/to/my.jar!/com/example/(immerhin das Ausrufezeichen).

Ist der Unterschied zwischen URI und URL  in Java dass ersteres keine Leerzeichen codiert? Vgl. Dateien, URIs und URLs, die in Java in Konflikt stehen (Diese Antwort erklärt die allgemein, konzeptionell Unterschied zwischen den beiden Begriffen ziemlich gut: URIs identifizieren und URLs lokalisieren;)

Zuletzt - und am wichtigsten - Warum brauche ich? File Objekt; Warum ist keine Ressource (URL) genug? (Und gibt es ein Ressourcenobjekt?)

Entschuldigung, wenn diese Frage etwas unorganisiert ist; es spiegelt nur die Verwirrung wider, die ich habe ... :)


76
2018-01-08 16:43


Ursprung


Antworten:


UPDATE 2017-04-12 Prüfen JvRs Antwort da es eine ausführlichere und genauere Erklärung enthält!


Bitte beachten Sie, dass ich mich nicht 100% kompetent bin zu beantworten, aber dennoch hier einige Kommentare:

  • File stellt eine Datei oder ein Verzeichnis dar, auf die über das Dateisystem zugegriffen werden kann
  • Ressource ist ein allgemeiner Begriff für ein Datenobjekt, das von der Anwendung geladen werden kann
    • gewöhnlich Ressourcen sind Dateien, die mit der Anwendung / Bibliothek verteilt und über den Klassenlademechanismus geladen werden (wenn sie sich auf dem Klassenpfad befinden)
  • URL#getPath ist Getter auf dem Pfad Teil der URL (protocol://host/path?query)
  • URL#getFile wie per JavaDoc zurückgegeben path+query

In Java, URI ist nur eine Datenstruktur zum Manipulieren des generischen Bezeichners selbst.

URL Auf der anderen Seite ist wirklich ein Ressourcen-Locator und bietet Ihnen Funktionen, um die Ressource tatsächlich über registrierte lesen URLStreamHandlers.

URLs können zu Dateisystemressourcen führen, und Sie können URLs für jede Dateisystemressource mithilfe von erstellen file:// Protokoll (daher File <-> URL Beziehung).

Beachten Sie auch, dass das URL#getFile hat nichts damit zu tun java.io.File.


Warum brauche ich Dateiobjekt; Warum reicht eine Ressource (URL) nicht aus?

Es reicht. Nur wenn Sie die Ressource an eine Komponente übergeben wollen, die nur mit Dateien arbeiten kann, müssen Sie sie bekommen Filedavon. Es können jedoch nicht alle Ressourcen-URLs in konvertiert werden Files.

Und gibt es ein Ressourcenobjekt?

Aus Sicht der JRE ist das nur ein Begriff. Einige Frameworks bieten Ihnen eine solche Klasse (z. Quelle des Frühlings).


37
2018-01-08 16:58



Ich bin gerade total verwirrt - hauptsächlich wegen der Terminologie, denke ich. Kann mir bitte jemand die Unterschiede erklären oder ein paar Links zu dummy-sicherem Material geben? Vor allem URI zu URL und Ressource zu Datei? Für mich fühlt es sich an, als ob sie das gleiche sein sollten ...

Die Terminologie ist verwirrend und manchmal verwirrend und stammt hauptsächlich aus der Evolution von Java als API und als Plattform im Laufe der Zeit. Um zu verstehen, wie diese Begriffe zu dem wurden, was sie tun, ist es wichtig, zwei Dinge zu erkennen, die das Design von Java beeinflussen:

  • Rückwärtskompatibilität.  Alte Anwendungen sollten auf neueren Installationen ausgeführt werden, idealerweise ohne Änderungen. Dies bedeutet, dass eine alte API (mit ihren Namen und ihrer Terminologie) in allen neueren Versionen beibehalten werden muss.
  • Plattformübergreifend  Die API sollte eine nutzbare Abstraktion der zugrunde liegenden Plattform bereitstellen, unabhängig davon, ob es sich um ein Betriebssystem oder einen Browser handelt.

Ich werde durch die Konzepte gehen und wie sie entstanden sind. Danach beantworte ich deine anderen, spezifischen Fragen, weil ich mich im ersten Teil vielleicht auf etwas beziehen muss.

Was ist eine "Ressource"?

Ein abstraktes, generisches Stück Daten, das gefunden und gelesen werden kann.  Locker gesagt, Java verwendet dies, um auf eine "Datei" zu verweisen, die möglicherweise keine Datei ist, aber ein benanntes Datenelement darstellt. Es hat keine direkte Klassen- oder Schnittstellendarstellung in Java, aber wegen seiner Eigenschaften (lokalisierbar, lesbar) wird es oft durch eine URL dargestellt.

Da eines der frühen Java-Designziele darin bestand, innerhalb eines Browsers als Sandbox-Anwendung (Applets!) Mit sehr eingeschränkten Rechten / Privilegien / Sicherheitsfreigabe ausgeführt zu werden, Java macht einen klaren (theoretischen) Unterschied zwischen einer Datei (etwas auf dem lokalen Dateisystem) und einer Ressource (etwas, das es lesen muss).  Aus diesem Grund wird etwas gelesen, das sich auf die Anwendung bezieht (Symbole, Klassendateien usw.) ClassLoader.getResource und nicht durch die Dateiklasse.

Leider, weil "Ressource" auch ein nützlicher Oberbegriff ist draußen von dieser Interpretation wird es auch verwendet, um sehr spezifische Dinge (z. B. Klasse Ressourcenbundle, UIResource, Ressource) Das ist in diesem Sinne keine Ressource.

Die Hauptklassen, die einen Pfad zu einer Ressource darstellen, sind java.nio.file.Path, java.io.File, java.net.URI, und java.net.URL.

Datei (java.io, 1.0)

Eine abstrakte Darstellung von Datei- und Verzeichnispfadnamen.

Die Klasse File repräsentiert eine Ressource, die erreichbar über das native Dateisystem der Plattform. Es enthält nur den Namen der Datei, es handelt sich also eher um einen Pfad (siehe später), den die Host-Plattform nach eigenen Einstellungen, Regeln und Syntax interpretiert.

Beachten Sie, dass die Datei nicht auf etwas zeigen muss lokal, etwas, das die Host-Plattform im Zusammenhang mit dem Dateizugriff versteht, z.B. ein UNC-Pfad in Windows. Wenn Sie eine ZIP-Datei als Dateisystem in Ihrem Betriebssystem bereitstellen, liest File die darin enthaltenen Einträge problemlos.

URL (java.net, 1.0)

Klassen-URL repräsentiert einen Uniform Resource Locator, einen Zeiger auf eine "Ressource" im World Wide Web. Eine Ressource kann so einfach sein wie eine Datei oder ein Verzeichnis oder eine Referenz auf ein komplizierteres Objekt, z. B. eine Abfrage an eine Datenbank oder an eine Suchmaschine.

Zusammen mit dem Konzept einer Ressource repräsentiert die URL diese Ressource genauso wie die Dateiklasse eine Datei in der Host-Plattform darstellt: z Eine strukturierte Zeichenfolge, die auf eine Ressource verweist.  Die URL enthält zusätzlich ein Schema, das darauf hinweist, wie die Ressource zu erreichen ist (wobei "file:" die "ask the host platform" ist) und somit auf Ressourcen über HTTP, FTP, innerhalb einer JAR und so weiter zeigen kann.

Leider haben URLs ihre eigene Syntax und Terminologie, einschließlich der Verwendung von "Datei" und "Pfad". Wenn die URL eine Datei-URL ist, gibt URL.getFile eine Zeichenfolge zurück, die identisch mit der Pfadzeichenfolge der referenzierten Datei ist.

Class.getResource gibt eine URL zurück: Sie ist flexibler als das Zurückgeben von Datei, und sie hat den Anforderungen des Systems in den frühen 1990er Jahren entsprochen.

URI (java.net, 1.4)

Stellt eine URI-Referenz (Uniform Resource Identifier) ​​dar.

URI ist eine (leichte) Abstraktion über URL.  Der Unterschied zwischen URI und URL ist konzeptionell und meist akademisch, aber URI ist formal besser definiert und deckt einen größeren Bereich von Anwendungsfällen ab. Da URL und URI nicht identisch sind / waren, wurde eine neue Klasse eingeführt, um sie darzustellen, wobei sich die Methoden URI.toURL und URL.toURI zwischen den beiden Methoden bewegen.

In Java besteht der Hauptunterschied zwischen URL und URI darin Eine URL trägt die Erwartung, dass sie auflösbar ist, etwas, von dem die Anwendung möglicherweise einen InputStream möchte; ein URI wird eher wie ein abstraktes thingamajig behandelt Macht auf etwas Auflösbares zeigen (und tut es normalerweise), aber was es bedeutet und wie man es erreicht, ist offener für Kontext und Interpretation.

Pfad (java.nio.file, 1.7)

Ein Objekt, das zum Suchen einer Datei in einem Dateisystem verwendet werden kann. Es wird normalerweise einen systemabhängigen Dateipfad darstellen.

Die neue Datei-API, die in der Path-Schnittstelle symbolisiert ist, ermöglicht eine wesentlich größere Flexibilität, als die File-Klasse bieten könnte. Die Pfadschnittstelle ist ein Abstraktion der Klasse Dateiund ist Teil der Neue IO-Datei-API. Wo Datei notwendigerweise auf eine "Datei" verweist, wie sie von der Host-Plattform verstanden wird, ist Pfad allgemeiner: es repräsentiert eine Datei (Ressource) in einem willkürlich Dateisystem.

Path entfernt die Abhängigkeit vom Konzept der Host-Plattform einer Datei. Dies kann ein Eintrag in einer ZIP-Datei, eine über FTP oder SSH-FS erreichbare Datei, eine mehrfach verwurzelte Darstellung des Klassenpfads der Anwendung oder wirklich alles sein, was über die FileSystem-Schnittstelle und ihren Treiber FileSystemProvider sinnvoll dargestellt werden kann. Es bringt die Macht des "Montierens" von Dateisystemen in den Kontext einer Java-Anwendung.

Die Host-Plattform wird durch das "Standard-Dateisystem" repräsentiert; wenn du anrufst File.toPath, erhalten Sie einen Pfad auf dem Standard-Dateisystem.


Wenn ich jetzt einen Locator habe, der auf eine Klasse oder ein Paket in einer JAR-Datei verweist, werden sich diese beiden (d. H. Pfadangaben für eine Datei) unterscheiden?

Unwahrscheinlich. Wenn sich die JAR-Datei im lokalen Dateisystem befindet, sollten Sie keine Abfragekomponente haben URL.getPath und URL.getFile sollte das gleiche Ergebnis zurückgeben. Wählen Sie jedoch die Datei aus, die Sie benötigen: Datei-URLs enthalten normalerweise keine Abfragekomponenten, aber ich könnte trotzdem eine hinzufügen.

Zuletzt - und am wichtigsten - warum brauche ich File-Objekt; Warum reicht eine Ressource (URL) nicht aus?

Die URL ist möglicherweise nicht ausreichend, weil Sie mit File Zugriff auf Verwaltungsdaten wie Berechtigungen (lesbar, schreibbar, ausführbar), Dateityp (bin ich ein Verzeichnis?) Und die Möglichkeit, das lokale Dateisystem zu durchsuchen und zu bearbeiten, erhalten. Wenn dies Funktionen sind, die Sie benötigen, können Sie diese über Datei oder Pfad bereitstellen.

Sie benötigen keine Datei, wenn Sie Zugriff auf Pfad haben. Einige ältere APIs benötigen jedoch möglicherweise Datei.

(Und gibt es ein Ressourcenobjekt?)

Nein, da ist es nicht. Es gibt viele Dinge, die so genannt werden, aber sie sind keine Ressource im Sinne von ClassLoader.getResource.


26
2017-11-21 16:56



Pavel Horals Antwort ist nett.

Wie er sagt, hat das Wort "Datei" völlig unterschiedliche Bedeutungen URL#getFile vs java.io.File - Vielleicht ist das ein Teil der Verwirrung.

Nur um hinzuzufügen:

  • EIN Ressource in Java ist ein abstraktes Konzept, eine Quelle von Daten, die gelesen werden können. Der Speicherort (oder die Adresse) einer Ressource wird in Java durch a dargestellt URL Objekt.

  • EIN Ressource kann einer regulären Datei im lokalen Dateisystem entsprechen (genauer gesagt, wenn URL beginnt mit file://). Aber eine Ressource ist allgemeiner (es kann auch eine Datei sein, die in einem Jar gespeichert ist, oder einige Daten, die aus dem Netzwerk oder aus dem Speicher gelesen werden, oder ...). Und es ist auch begrenzter, weil a File (neben anderen Dingen als eine normale Datei: ein Verzeichnis, ein Link) kann auch erstellt und geschrieben werden.

  • Denken Sie in Java a File Objekt stellt nicht wirklich "eine Datei" dar, sondern den Ort (den vollständigen Namen, mit Pfad) einer Datei. Also, a File Objekt ermöglicht es Ihnen, eine Datei zu finden (und zu öffnen), als URLermöglicht es Ihnen, auf eine Ressource zuzugreifen (und sie zu öffnen). (Es gibt kein Resource Klasse in Java, um eine Ressource darzustellen, aber es gibt auch keine, die eine Datei darstellt! einmal mehr : File ist keine Datei, sondern der Pfad einer Datei).


11
2018-01-08 17:49



So wie ich sie verstehe, könntest du sie wie folgt kategorisieren:

Web-basiert: URIs und URLs.

  • URLs: Eine URL ist ein bestimmter Ort auf dem Internet (nur eine normale Webadresse wie - stackoverflow.com)
  • URIs: Ever URL ist ein URI. Aber URIs können auch Dinge wie "mailto:" enthalten, also sind sie auch, naja, was von einem "Skript" würde ich sagen.

Und lokal: Ressource, Pfad und Dateien

  • Ressource: Ressourcen sind Dateien in Ihrem Jar. Sie werden verwendet, um Dateien aus Gläsern / Containern zu laden.
  • Pfad: Ein Pfad ist im Grunde eine Zeichenfolge. Aber es kommt mit einigen praktischen Funktionen, um mehrere Zeichenfolgen zu verketten oder Dateien zu einer Zeichenfolge hinzuzufügen. Es stellt sicher, dass der Pfad, den Sie erstellen, gültig ist.
  • Datei: Dies ist ein Verweis auf ein Verzeichnis oder eine Datei. Es wird verwendet, um Dateien zu ändern, sie zu öffnen usw.

Es wäre einfacher, wenn sie in einer Klasse zusammengefasst würden - sie sind wirklich verwirrend: D

Ich hoffe das hilft dir :)

(Ich habe mir gerade die Dokumentation angesehen - siehe docs.oracle.com)


3
2018-01-08 17:02



Eine Datei ist eine abstrakte Darstellung einer Entität im lokalen Dateisystem.

Ein Pfad ist im Allgemeinen eine Zeichenfolge, die den Speicherort einer Datei in einem Dateisystem angibt. Es enthält normalerweise nicht den Dateinamen. So hätte c: \ documents \ mystuff \ stuff.txt einen Pfad mit dem Wert von "C: \ documents \ mystuff". Offensichtlich würde das Format von absoluten Dateinamen und Pfaden enorm von Dateisystem zu Dateisystem variieren.

Die URL ist eine URI-Untergruppe, wobei die URL normalerweise Ressourcen darstellt, die über http zugänglich sind. Ich glaube nicht, dass es eine Art eiserne Regel darüber gibt, wann etwas eine URI oder eine URL sein muss. URIs sind Zeichenfolgen in der Form von "protocol: // resource-identifier" wie bitcoin: // params, http://something.com?param=value. Klassen wie URL umhüllen in der Regel die Zeichenfolge und stellen Hilfsmethoden bereit, für die String keinen Grund hätte.

Keine Ressource, zumindest nicht in dem Sinne, von dem du sprichst. Nur weil eine Methode getResource heißt, bedeutet das nicht, dass sie ein Objekt vom Typ Resource zurückgibt.

Letztlich ist der beste Weg herauszufinden, was die Methoden einer Klasse tun, ist eine Instanz davon in Ihrem Code zu erstellen, rufen Sie die Methoden auf und gehen Sie dann entweder im Debug-Modus durch oder senden Sie die Ergebnisse an System.out.


0
2018-01-08 17:08