getResourceAsStream() vs FileInputStream
Ich versuche, eine Datei zu laden, die in einer webapp, und ich war immer ein FileNotFound
Ausnahme, wenn ich FileInputStream
. Jedoch mit dem gleichen Pfad, ich war in der Lage, um die Datei zu laden, wenn ich nicht getResourceAsStream()
.
Was ist der Unterschied zwischen den beiden Methoden, und warum geht man arbeiten, während der andere nicht?
InformationsquelleAutor Vivin Paliath | 2010-02-22
Du musst angemeldet sein, um einen Kommentar abzugeben.
Den
java.io.File
und Konsorten wirkt auf das lokale Dateisystem. Die Ursache des Problems ist, dass relative Pfade injava.io
sind abhängig vom aktuellen Arbeitsverzeichnis. I. e. das Verzeichnis, aus dem die JVM (in Ihrem Fall: der webserver ist) gestartet wird. Dies kann zum BeispielC:\Tomcat\bin
oder etwas ganz anderes, aber so nichtC:\Tomcat\webapps\contextname
oder was auch immer Sie erwarten würde es zu sein. In einem normalen Eclipse-Projekt, das wäreC:\Eclipse\workspace\projectname
. Sie können erfahren Sie mehr über das aktuelle Arbeits-Verzeichnis die folgende Weise:Aber das Arbeitsverzeichnis ist in keiner Weise programmatisch steuerbar. Sie sollten wirklich lieber mit absolute Pfade in der
File
- API anstelle von relativen Pfaden. E. g.C:\full\path\to\file.ext
.Wollen Sie nicht zu fest oder zu erraten den absoluten Pfad in Java (web -) Anwendungen. Das ist nur die Portabilität Probleme (d.h. es läuft in system X, aber nicht in system Y). Die normale Praxis ist, diese Art von Ressourcen, die in der classpath, oder fügen Sie den vollständigen Pfad zum Klassenpfad (in einer IDE wie Eclipse, dass die
src
Ordner und die "build path" bezeichnet). Auf diese Weise können Sie Sie nehmen mit Hilfe derClassLoader
durchClassLoader#getResource()
oderClassLoader#getResourceAsStream()
. Es ist in der Lage, suchen Sie die Dateien relativ zum "root" des classpath, als Sie durch Zufall herausgefunden. In Webapplikationen (oder jede andere Anwendung, die mit mehreren classloadern) es wird empfohlen, verwenden Sie dieClassLoader
zurückgegeben durchThread.currentThread().getContextClassLoader()
für diese so können Sie sich "außerhalb" der webapp Kontext.Andere alternative in webapps ist die
ServletContext#getResource()
und sein GegenstückServletContext#getResourceAsStream()
. Es ist in der Lage, auf Dateien zuzugreifen, die sich in der öffentlichkeitweb
Ordner der webapp-Projekt, einschließlich der/WEB-INF
Ordner. DieServletContext
ist in servlets durch die übernommenengetServletContext()
Methode, Sie können es nennen, wie Sie ist.Siehe auch:
Verwandte: stackoverflow.com/questions/7952090/...
InformationsquelleAutor BalusC
getResourceAsStream
ist der richtige Weg, es zu tun für web-Anwendungen (wie Sie bereits gelernt).Der Grund dafür ist, dass das Lesen aus der Datei system kann nicht funktionieren, wenn Verpacken Sie Ihre web-app in einem KRIEG. Dies ist der richtige Weg, um Paket eine web-app. Es ist tragbar, denn Sie sind nicht abhängig von einem absoluten Datei-Pfad oder der Ort, wo sich Ihre app-server installiert ist.
duffy, sehr nette Antwort und Sie erklärte, was mein Fehler war, aber BalusC ging in eine Menge von detail - ich glaube, seine Antwort wäre hilfreich für Leute, die wissen möchten, den inneren details. Hoffnung Sie don T Geist mich ändern die akzeptierte Antwort auf seine Frage!
Ich glaube nicht, dass "keine Arbeit" ist zu stark. Sogar etwas so einfaches wie das bereitgestellt wird auf zwei verschiedenen Servern mit verschiedenen Pfade zu den app-server wird es brechen. Der Punkt ist, dass Sie brauchen, um Ihren KRIEG als self-contained wie möglich. Dein Punkt ist richtig, aber ich werde bleiben, um meine Fassung.
InformationsquelleAutor duffymo
FileInputStream lädt der Pfad der Datei übergeben Sie an den Konstruktor als Verwandte aus der Arbeitsverzeichnis des Java-Prozesses. In der Regel in einem web-container, das ist so etwas wie die
bin
Ordner.getResourceAsStream()
laden einen Datei-Pfad relativ aus der Anwendung classpath.InformationsquelleAutor matt b
Den
FileInputStream
Klasse arbeitet direkt mit dem zugrunde liegenden Dateisystem. Wenn die betreffende Datei ist physisch nicht vorhanden, es wird scheitern, um es zu öffnen. DiegetResourceAsStream()
- Methode funktioniert anders. Es versucht, zu suchen und laden Sie die Ressource mit derClassLoader
von der Klasse aufgerufen wird. Dies ermöglicht es zu finden, zum Beispiel, Ressourcen eingebettet injar
- Dateien.Gut, ja, natürlich. Aber Sie sind in der Regel nicht etwas gesehen, als unabhängige Entitäten in der Datei-system, es sei denn, Sie wissen, geschieht über die
jar
- Datei-format und seine Auswirkungen. Und in Java, die entsprechendeClassLoader
könnte diese Erkenntnis haben, in der Erwägung, dass eine nurFileInputStream
sicher nicht.InformationsquelleAutor Dirk
classname.getResourceAsStream() lädt eine Datei über den classloader des Klassennamens. Wenn die Klasse kam aus einer jar-Datei, die ist, wo die Ressourcen geladen werden.
FileInputStream dient zum Lesen einer Datei aus dem Dateisystem.
InformationsquelleAutor Lachlan Roche
Hier bin ich durch die Trennung sowohl der Nutzungen durch markieren Sie als Datei Read(java.io) und Ressource Lesen(ClassLoader.getResourceAsStream()).
Datei Lesen -
1. Funktioniert auf dem lokalen Dateisystem.
2. Versucht, die angeforderte Datei aus der aktuellen JVM gestartet Verzeichnis als root
3. Idealerweise gute bei der Verwendung von Dateien für die Verarbeitung in einer vorbestimmten Lage, wie,/dev/Dateien oder C:\Data.
Ressource Lesen -
1. Funktioniert auf Klasse Weg
2. Versucht, suchen Sie die Datei/Ressource im aktuellen oder übergeordneten classloader classpath.
3. Idealerweise gute beim laden von Dateien aus gepackten Dateien, wie Krieg oder Glas.
InformationsquelleAutor Aditya Bhuyan