Ich schaue mir gerade einen Teil des Java-Codes an, der einen Pfad als Zeichenfolge verwendet und dessen URL verwendet URL resource = ClassLoader.getSystemClassLoader().getResource(pathAsString);
, dann aufruft String path = resource.getPath()
und schließlich ausführt new File(path);
.
Oh, und es gibt auch Anrufe nach URL url = resource.toURI();
und String file = resource.getFile()
.
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 ...
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 wahrscheinlich meinen Geisteszustand erheblich erweitert ...)
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)?
resource.toString()
würde Ihnen schließlich geben jar:file:/C:/path/to/my.jar!/com/example/
(beachten Sie das Ausrufezeichen).
Ist der Unterschied zwischen URI und URL in Java, dass erstere keine Leerzeichen codieren? Vgl. Dateien, URIs und URLs, die in Java in Konflikt stehen (Diese Antwort erklärt den allgemeinen konzeptionellen Unterschied zwischen den beiden Begriffen ziemlich gut: URIs identifizieren und URLs lokalisieren; )
Schließlich - und vor allem - warum brauche ich ein File
Objekt? Warum reicht eine Ressource ( URL
) nicht aus? (Und gibt es ein Ressourcenobjekt?)
Entschuldigung, wenn diese Frage etwas unorganisiert ist. es spiegelt nur die Verwirrung wider, die ich habe ... :)
quelle
Path
FileSystem von NIOURL
ist undurchsichtig - wie Sie zeigenjar:file:
, dh eine Ressource in einem.jar
Archiv. EsFile
ist sehr unwahrscheinlich, dass etwas Nützliches daraus wird.Antworten:
UPDATE 2017-04-12 Überprüfen Sie die Antwort von JvR, da sie ausführlichere und genauere Erklärungen enthält!
Bitte beachten Sie, dass ich mich nicht als 100% kompetent zur Beantwortung betrachte, aber dennoch hier einige Kommentare:
File
stellt eine Datei oder ein Verzeichnis dar, auf die bzw. das über das Dateisystem zugegriffen werden kannURL#getPath
ist Getter auf dem Pfad Teil von URL (protocol://host/path?query
)URL#getFile
gemäß JavaDoc zurückpath+query
In Java
URI
ist dies nur eine Datenstruktur zum Bearbeiten des generischen Bezeichners selbst.URL
Auf der anderen Seite ist es wirklich ein Ressourcen-Locator und bietet Ihnen Funktionen, um die Ressource tatsächlich über registrierteURLStreamHandler
s zu lesen .URLs können zu Dateisystemressourcen führen, und Sie können mithilfe eines
file://
Protokolls (daherFile
<->URL
Beziehung) eine URL für jede Dateisystemressource erstellen .Beachten Sie auch, dass dies
URL#getFile
nichts damit zu tun hatjava.io.File
.Es reicht. Nur wenn Sie die Ressource an eine Komponente übergeben möchten, die nur mit Dateien arbeiten kann, müssen Sie sie abrufen
File
. Es können jedoch nicht alle Ressourcen-URLs inFile
s konvertiert werden .Aus Sicht der JRE ist es nur ein Begriff. Einige Frameworks bieten Ihnen eine solche Klasse (z. B. Spring's Resource ).
quelle
java.nio.file.Path
, was im Grunde ein (Java 7+) Ersatz für istjava.io.File
, da die letztere API in den frühen Tagen von Java anscheinend schlecht durchdacht war.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:
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)
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)
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)
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)
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.Unwahrscheinlich. Wenn die JAR - Datei auf dem lokalen Dateisystem ist, sollten Sie keine Abfragekomponente haben, so
URL.getPath
undURL.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.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.
Nein, gibt es nicht. Es gibt viele ähnliche Dinge, aber sie sind keine Ressource im Sinne von
ClassLoader.getResource
.quelle
Pavel Horals Antwort ist nett.
Wie er sagt, hat das Wort "Datei" in
URL#getFile
vs völlig unterschiedliche (praktisch nicht verwandte) Bedeutungenjava.io.File
- vielleicht ist das ein Teil der Verwirrung.Nur um hinzuzufügen:
Eine Ressource in Java ist ein abstraktes Konzept, eine Datenquelle, die gelesen werden kann. Der Speicherort (oder die Adresse) einer Ressource wird in Java durch ein
URL
Objekt dargestellt.Eine Ressource kann einer regulären Datei im lokalen Dateisystem entsprechen (insbesondere, wenn sie mit
URL
beginntfile://
). Eine Ressource ist jedoch allgemeiner (es kann sich auch um eine in einem JAR gespeicherte Datei oder um Daten handeln, die aus dem Netzwerk oder aus dem Speicher gelesen werden sollen, oder ...). Und es ist auch eingeschränkter, weil eineFile
(abgesehen davon, dass es sich nicht um eine normale Datei handelt: ein Verzeichnis, ein Link) auch erstellt und in diese geschrieben werden kann.Denken Sie daran, dass in Java ein
File
Objekt nicht wirklich "eine Datei" darstellt, sondern den Speicherort (den vollständigen Namen mit Pfad) einer Datei. Mit einemFile
Objekt können Sie also eine Datei suchen (und öffnen), währendURL
Sie auf eine Ressource zugreifen (und diese öffnen) können. (Resource
In Java gibt es keine Klasse, die eine Ressource darstellt, aber auch keine, die eine Datei darstellt! Noch einmal: EsFile
handelt sich nicht um eine Datei, sondern um den Pfad einer Datei.)quelle
So wie ich sie verstehe, können Sie sie wie folgt kategorisieren:
Webbasiert: URIs und URLs.
Und lokal: Ressource, Pfad und Dateien
Es wäre einfacher, wenn sie zu 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)
quelle
Eine Datei ist eine abstrakte Darstellung einer Entität im lokalen Dateisystem.
Ein Pfad ist im Allgemeinen eine Zeichenfolge, die den Speicherort einer Datei innerhalb eines Dateisystems angibt. Der Dateiname ist normalerweise nicht enthalten. C: \ documents \ mystuff \ stuff.txt hätte also einen Pfad mit dem Wert "C: \ documents \ mystuff". Offensichtlich würde das Format der absoluten Dateinamen und Pfade von Dateisystem zu Dateisystem enorm variieren.
URL ist ein Susbset von URI, wobei URL normalerweise Ressourcen darstellt, auf die über http zugegriffen werden kann. Ich glaube nicht, dass es irgendeine ironclad Regel gibt, wann etwas eine URI gegen eine URL sein muss. URIs sind Zeichenfolgen in Form von "protocol: // resource-identifier" wie bitcoin: // params, http://something.com?param=value . Klassen wie URL umschließen im Allgemeinen die Zeichenfolge und stellen Dienstprogrammmethoden bereit, für die String keinen Grund zur Angabe hätte.
Keine Ressource, zumindest nicht in dem Sinne, von dem Sie sprechen. Nur weil eine Methode getResource heißt, heißt das nicht, dass sie ein Objekt vom Typ Resource zurückgibt.
Der beste Weg, um herauszufinden, was die Methoden einer Klasse tun, besteht darin, eine Instanz davon in Ihrem Code zu erstellen, die Methoden aufzurufen und dann entweder im Debug-Modus durchzugehen oder die Ergebnisse an System.out zu senden.
quelle