Ich möchte eine Ressource aus meinem Glas so lesen:
File file;
file = new File(getClass().getResource("/file.txt").toURI());
BufferredReader reader = new BufferedReader(new FileReader(file));
//Read the file
und es funktioniert gut, wenn es in Eclipse ausgeführt wird, aber wenn ich es in ein JAR exportiere, gibt es eine IllegalArgumentException:
Exception in thread "Thread-2"
java.lang.IllegalArgumentException: URI is not hierarchical
und ich weiß wirklich nicht warum, aber bei einigen Tests habe ich festgestellt, ob ich mich ändere
file = new File(getClass().getResource("/file.txt").toURI());
zu
file = new File(getClass().getResource("/folder/file.txt").toURI());
dann funktioniert es umgekehrt (es funktioniert im Glas, aber nicht in der Finsternis).
Ich verwende Eclipse und der Ordner mit meiner Datei befindet sich in einem Klassenordner.
getResourceAsStream
ist immer noch eine einfachere und tragbarere Lösung für das Problem.Antworten:
Anstatt zu versuchen, die Ressource als Datei zu adressieren, bitten Sie den ClassLoader , stattdessen über getResourceAsStream einen InputStream für die Ressource zurückzugeben :
Solange die
file.txt
Ressource im Klassenpfad verfügbar ist, funktioniert dieser Ansatz auf dieselbe Weise, unabhängig davon, ob sich diefile.txt
Ressource in einemclasses/
Verzeichnis oder in einem befindetjar
.Das
URI is not hierarchical
tritt auf, weil die URI für eine Ressource innerhalb einer JAR - Datei wird in etwa so aussehen werde:file:/example.jar!/file.txt
. Sie können die Einträge in einerjar
(einerzip
Datei) nicht lesen, als wäre es eine einfache alte Datei .Dies wird gut erklärt durch die Antworten auf:
quelle
InputStream
vorhanden ist (wieFile.exists()
), damit mein Spiel erkennen kann, ob die Standarddatei verwendet werden soll oder nicht. Vielen Dank.getClass().getResource("**/folder**/file.txt")
, warum es funktioniert hat, ist, dass ich diesen Ordner im selben Verzeichnis wie mein Glas hatte :).getResourceAsStream
Gibt null zurück, wenn die Ressource nicht vorhanden ist, sodass dies Ihr "vorhandener" Test sein kann.Um auf eine Datei in einem Glas zuzugreifen, haben Sie zwei Möglichkeiten:
Platzieren Sie die Datei in einer Verzeichnisstruktur, die Ihrem Paketnamen entspricht (nach dem Extrahieren der JAR-Datei sollte sie sich im selben Verzeichnis wie die .class-Datei befinden), und greifen Sie dann mit darauf zu
getClass().getResourceAsStream("file.txt")
Platzieren Sie die Datei im Stammverzeichnis (nach dem Extrahieren der JAR-Datei sollte sie sich im Stammverzeichnis befinden) und greifen Sie dann mit darauf zu
Thread.currentThread().getContextClassLoader().getResourceAsStream("file.txt")
Die erste Option funktioniert möglicherweise nicht, wenn jar als Plugin verwendet wird.
quelle
Ich hatte dieses Problem schon einmal und habe einen Fallback-Weg zum Laden gemacht. Grundsätzlich funktioniert der erste Weg innerhalb einer JAR-Datei und der zweite Weg innerhalb von Eclipse oder einer anderen IDE.
quelle
Bis jetzt (Dezember 2017) ist dies die einzige Lösung, die ich gefunden habe und die sowohl innerhalb als auch außerhalb der IDE funktioniert .
Verwenden Sie PathMatchingResourcePatternResolver
Hinweis: Es funktioniert auch im Spring-Boot
In diesem Beispiel lese ich einige Dateien in src / main / resources / my_folder :
quelle
Das Problem ist, dass bestimmte Bibliotheken von Drittanbietern Dateipfadnamen anstelle von Eingabestreams benötigen. Die meisten Antworten sprechen dieses Problem nicht an.
In diesem Fall besteht eine Problemumgehung darin, den Ressourceninhalt in eine temporäre Datei zu kopieren. Im folgenden Beispiel werden jUnits verwendet
TemporaryFolder
.quelle
Wenn Sie als Datei lesen möchten, gibt es meiner Meinung nach immer noch eine ähnliche Lösung:
quelle
file:
URL ist.Stellen Sie sicher, dass Sie mit dem richtigen Trennzeichen arbeiten. Ich habe alle
/
in einem relativen Pfad durch a ersetztFile.separator
. Dies funktionierte in der IDE einwandfrei, in der Build-JAR jedoch nicht.quelle
Ich denke, das sollte auch in Java funktionieren. Der folgende Code, den ich benutze, verwendet Kotlin.
quelle
Ich habe eine Lösung gefunden
Ersetzen Sie "Main" durch die Java-Klasse, in der Sie es codiert haben. Ersetzen Sie "path" durch den Pfad in der JAR-Datei.
Wenn Sie beispielsweise State1.txt in das Paket com.issac.state einfügen, geben Sie den Pfad als "/ com / issac / state / State1" ein, wenn Sie Linux oder Mac ausführen. Wenn Sie Windows ausführen, geben Sie den Pfad als "\ com \ issac \ state \ State1" ein. Fügen Sie der Datei die Erweiterung .txt nur hinzu, wenn die Ausnahme Datei nicht gefunden auftritt.
quelle
Sie können den Klassenlader verwenden, der aus dem Klassenpfad als ROOT-Pfad liest (ohne "/" am Anfang).
quelle
Wenn Sie spring verwenden, können Sie die folgende Methode verwenden, um Dateien aus src / main / resources zu lesen:
quelle
Aus irgendeinem Grund wurde
classLoader.getResource()
immer null zurückgegeben, wenn ich die Webanwendung für WildFly 14 bereitgestellt habe. ClassLoader von null wird abgerufengetClass().getClassLoader()
oderThread.currentThread().getContextClassLoader()
zurückgegeben.getClass().getClassLoader()
API-Dokument sagt,"Gibt den Klassenlader für die Klasse zurück. Einige Implementierungen verwenden möglicherweise null, um den Bootstrap-Klassenlader darzustellen. Diese Methode gibt in solchen Implementierungen null zurück, wenn diese Klasse vom Bootstrap-Klassenlader geladen wurde."
Wenn Sie WildFly und Ihre Webanwendung verwenden, versuchen Sie dies möglicherweise
request.getServletContext().getResource()
gab die Ressourcen-URL zurück. Hier ist request ein Objekt von ServletRequest.quelle
Der folgende Code funktioniert mit Spring Boot (Kotlin):
quelle