Ich lade eine Textdatei aus einem Paket in einem kompilierten JAR von meinem Java-Projekt. Die entsprechende Verzeichnisstruktur ist wie folgt:
/src/initialization/Lifepaths.txt
Der Code, der zum Laden der Datei verwendet wird, lautet:
public class Lifepaths {
public static void execute() {
System.out.println(Lifepaths.class.getClass().
getResourceAsStream("/initialization/Lifepaths.txt"));
}
private Lifepaths() {}
//This is temporary; will eventually be called from outside
public static void main(String[] args) {execute();}
}
Der Ausdruck wird immer null
ausgeben, egal was ich verwende. Ich bin mir nicht sicher, warum das oben genannte nicht funktionieren würde, also habe ich es auch versucht:
"/src/initialization/Lifepaths.txt"
"Initialisierung/Lebenspfade.txt"
"Lebenspfade.txt"
Keines dieser Programme funktioniert. Ich habe gelesen zahlreiche Fragen zu diesem Thema, aber keine davon war hilfreich - normalerweise sagen sie nur, dass man Dateien über den Root-Pfad laden soll, was ich bereits tue. Das, oder einfach die Datei aus dem aktuellen Verzeichnis laden (einfach Dateiname
laden), was ich auch schon versucht habe. Die Datei wird in die JAR-Datei am richtigen Ort und mit dem richtigen Namen kompiliert.
Wie kann ich das Problem lösen?
Lifepaths.class.getClass().getResourceAsStream(...)` lädt Ressourcen mit dem System Class Loader und schlägt offensichtlich fehl, weil er Ihre JARs nicht sieht
Lifepaths.class.getResourceAsStream(...)
lädt Ressourcen mit demselben Klassenlader, der auch die Lifepaths-Klasse geladen hat, und sollte Zugriff auf die Ressourcen in Ihren JARs haben
Die Regeln lauten wie folgt:
Und versuchen Sie es:
Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")
anstelle von
Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")
(ich bin mir nicht sicher, ob es einen Unterschied macht, aber ersteres wird den richtigen ClassLoader/ JAR verwenden, während ich mir bei letzterem nicht sicher bin)
Es gibt also mehrere Möglichkeiten, eine Ressource aus einem Jar abzurufen, und jede hat eine leicht unterschiedliche Syntax, bei der der Pfad anders angegeben werden muss.
Die beste Erklärung, die ich gesehen habe, ist dieser Artikel aus JavaWorld. Ich fasse hier zusammen, aber wenn Sie mehr wissen wollen, sollten Sie sich den Artikel ansehen.
Methoden
ClassLoader.getResourceAsStream()
. Format: "/"-getrennte Namen; kein führendes "/" (alle Namen sind absolut).
Beispiel: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
Class.getResourceAsStream()
Format: "/"-getrennte Namen; das führende "/" gibt absolute Namen an; alle anderen Namen sind relativ zum Paket der Klasse'.
Beispiel: this.getClass().getResourceAsStream("/some/pkg/resource.properties");