getResourceAsStream gibt null zurück

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?

Lösung

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

Kommentare (6)

Die Regeln lauten wie folgt:

  1. Überprüfen Sie den Speicherort der Datei, die Sie in das JAR laden wollen (und vergewissern Sie sich damit auch, dass sie dem JAR tatsächlich hinzugefügt wurde)
  2. Verwenden Sie entweder einen absoluten Pfad: der Pfad beginnt in der Wurzel des JARs
  3. Verwenden Sie einen relativen Pfad: der Pfad beginnt im Paketverzeichnis der Klasse, die Sie getResource/ getResoucreAsStream aufrufen

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)

Kommentare (3)

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

  1. ClassLoader.getResourceAsStream().

Format: "/"-getrennte Namen; kein führendes "/" (alle Namen sind absolut).

Beispiel: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");

  1. 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");

Kommentare (3)