Ich bin momentan total verwirrt - hauptsächlich wegen der Terminologie, denke ich. Kann mich bitte jemand durch die Unterschiede führen oder ein paar Links zu Dummy-Proof-Material bereitstellen? Besonders URI zu URL und Ressource zu Datei? Für mich fühlt es sich so an, als ob sie dasselbe sein sollten ...
Die Terminologie ist verwirrend und manchmal verwirrend und basiert hauptsächlich auf der Entwicklung von Java als API und als Plattform im Laufe der Zeit. Um zu verstehen, wie diese Begriffe zu ihrer Bedeutung führten, ist es wichtig, zwei Dinge zu erkennen, die das Design von Java beeinflussen:
- Abwä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 verwendbare 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. Ich werde Ihre anderen, spezifischen Fragen danach beantworten, da ich mich möglicherweise im ersten Teil auf etwas beziehen muss.
Was ist eine "Ressource"?
Ein abstraktes, allgemeines Datenelement, das gefunden und gelesen werden kann. 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 aufgrund seiner Eigenschaften (lokalisierbar, lesbar) wird es häufig durch eine URL dargestellt.
Da eines der frühen Entwurfsziele von Java darin bestand, innerhalb eines Browsers als Sandbox-Anwendung (Applets!) Mit sehr eingeschränkten Rechten / Privilegien / Sicherheitsfreigaben ausgeführt zu werden, macht Java einen klaren (theoretischen) Unterschied zwischen einer Datei (etwas auf lokaler Ebene) Dateisystem) und eine Ressource (etwas, das es lesen muss). Aus diesem Grund erfolgt das Lesen von Informationen zur Anwendung (Symbole, Klassendateien usw.) über ClassLoader.getResource
und nicht über die File-Klasse.
Da "Ressource" auch außerhalb dieser Interpretation ein nützlicher Oberbegriff ist , wird es leider auch verwendet, um sehr spezifische Dinge (z. B. Klasse ResourceBundle , UIResource , Resource ) zu benennen , die in diesem Sinne keine Ressource sind.
Die Hauptklassen (ein Pfad zu) einer Ressource 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 File-Klasse stellt eine Ressource dar, die über das native Dateisystem der Plattform erreichbar ist . Es enthält nur den Namen der Datei, es ist also eher ein Pfad (siehe später), den die Host-Plattform gemäß ihren eigenen Einstellungen, Regeln und Syntax interpretiert.
Beachten Sie, dass File nicht auf etwas Lokales verweisen muss, sondern nur auf etwas, das die Hostplattform im Kontext des Dateizugriffs versteht, z. B. einen UNC-Pfad in Windows. Wenn Sie eine ZIP-Datei als Dateisystem in Ihr Betriebssystem einbinden, liest File die darin enthaltenen Einträge einwandfrei.
URL (java.net, 1.0)
Die Klassen-URL stellt einen Uniform Resource Locator dar, einen Zeiger auf eine "Ressource" im World Wide Web. Eine Ressource kann so einfach wie eine Datei oder ein Verzeichnis sein oder ein Verweis auf ein komplizierteres Objekt, z. B. eine Abfrage an eine Datenbank oder eine Suchmaschine.
In Verbindung mit dem Konzept einer Ressource stellt die URL diese Ressource genauso dar wie die File-Klasse eine Datei auf der Host-Plattform: als strukturierte Zeichenfolge, die auf eine Ressource verweist. Die URL enthält außerdem ein Schema, das angibt, wie die Ressource erreicht werden kann (wobei "file:" "die Host-Plattform fragen" ist), und ermöglicht so das Zeigen auf Ressourcen über HTTP, FTP, innerhalb einer JAR und so weiter.
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 mit der Pfadzeichenfolge der referenzierten Datei identisch ist.
Class.getResource
Gibt eine URL zurück: Sie ist flexibler als die Rückgabe von Dateien und hat die Anforderungen des Systems erfüllt, wie sie in den frühen neunziger Jahren vorgestellt wurden.
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 ein breiteres Spektrum von Anwendungsfällen ab. Da URL und URI nicht dasselbe sind / waren, wurde eine neue Klasse eingeführt, um sie darzustellen, mit den Methoden URI.toURL und URL.toURI, um zwischen den beiden zu wechseln.
In Java besteht der Hauptunterschied zwischen URL und URI darin, dass eine URL die Erwartung hat, auflösbar zu sein , von der die Anwendung möglicherweise einen InputStream möchte. Ein URI wird eher wie ein abstraktes Ding behandelt, das auf etwas Auflösbares verweist (und dies normalerweise tut), aber was es bedeutet und wie man es erreicht, ist offener für Kontext und Interpretation.
Pfad (java.nio.file, 1.7)
Ein Objekt, mit dem eine Datei in einem Dateisystem gefunden werden kann. Es wird normalerweise einen systemabhängigen Dateipfad darstellen.
Die neue Datei-API, die in der Pfadoberfläche dargestellt ist, bietet eine viel größere Flexibilität, als die Dateiklasse bieten könnte. Die Pfadschnittstelle ist eine Abstraktion der File-Klasse und Teil der New IO File API . Wenn File notwendigerweise auf eine "Datei" verweist, wie sie von der Host-Plattform verstanden wird, ist Path allgemeiner: Es repräsentiert eine Datei (Ressource) in einem beliebigen Dateisystem.
Path nimmt die Abhängigkeit vom Konzept einer Datei auf der Host-Plattform. Dies kann ein Eintrag in einer ZIP-Datei sein, eine Datei, die über FTP oder SSH-FS erreichbar ist, eine mehrwurzelige Darstellung des Anwendungsklassenpfads oder wirklich alles, was über die FileSystem-Schnittstelle und ihren Treiber FileSystemProvider sinnvoll dargestellt werden kann. Es bringt die Fähigkeit, Dateisysteme in den Kontext einer Java-Anwendung zu "mounten".
Die Host-Plattform wird durch das "Standard-Dateisystem" dargestellt. Wenn Sie aufrufen File.toPath
, erhalten Sie einen Pfad im Standarddateisystem.
Wenn ich nun einen Locator habe, der auf eine Klasse oder ein Paket in einer JAR-Datei verweist, unterscheiden sich diese beiden (dh Pfad und Datei-Zeichenfolgen)?
Unwahrscheinlich. Wenn die JAR - Datei auf dem lokalen Dateisystem ist, sollten Sie keine Abfragekomponente haben, so URL.getPath
und URL.getFile
sollte das gleiche Ergebnis zurück. Wählen Sie jedoch die gewünschte aus: Datei-URLs enthalten normalerweise keine Abfragekomponenten, aber ich könnte trotzdem eine hinzufügen.
Zuletzt - und vor allem - warum brauche ich ein Dateiobjekt? Warum reicht eine Ressource (URL) nicht aus?
Die URL reicht möglicherweise nicht aus, da Sie mit File Zugriff auf Verwaltungsdaten wie Berechtigungen (lesbar, beschreibbar, ausführbar), Dateityp (bin ich ein Verzeichnis?) Und die Möglichkeit haben, das lokale Dateisystem zu durchsuchen und zu bearbeiten. Wenn Sie diese Funktionen benötigen, stellen Sie sie mit Datei oder Pfad bereit.
Sie benötigen keine Datei, wenn Sie Zugriff auf Path haben. Für einige ältere APIs ist möglicherweise eine Datei erforderlich.
(Und gibt es ein Ressourcenobjekt?)
Nein, gibt es nicht. Es gibt viele ähnliche Dinge, aber sie sind keine Ressource im Sinne von ClassLoader.getResource
.
Path
FileSystem von NIO