getResourceAsStreamはnullを返します。

私のJavaプロジェクトのコンパイル済みJARのパッケージ内からテキストファイルを読み込んでいます。関連するディレクトリ構造は以下の通りです。

/src/initialization/Lifepaths.txt

ファイルの読み込みに使用しているコードは

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();}
}

何を使っても、プリントアウトは常にnullと表示されます。なぜ上記の方法ではうまくいかないのかわからないので、以下の方法も試してみました。

  • "/src/initialization/Lifepaths.txt"
  • "initialization/Lifepaths.txt"
  • "Lifepaths.txt"

いずれも動作しません。このトピックに関しては、これまでにI'vereadmany ofquestionを読みましたが、どれも役に立ちませんでした。たいていは、ルートパスを使ってファイルをロードしろというだけで、私はすでにそうしています。それか、カレントディレクトリからファイルをロードする(単に load filename)か、それも試してみました。ファイルは適切な場所に適切な名前でJARにコンパイルされています。

これを解決するにはどうしたらいいでしょうか?

ソリューション

Lifepaths.class.getClass().getResourceAsStream(...)`は、システムクラスローダーを使用してリソースをロードしますが、あなたのJARが見えないので明らかに失敗します。

Lifepaths.class.getResourceAsStream(...) はLifepathsクラスをロードしたのと同じクラスローダを使ってリソースをロードし、あなたのJAR内のリソースにアクセスできるはずです。

解説 (6)

ルールは以下の通りです。

JAR内で読み込みたいファイルの位置を確認する(したがって、実際にJARに追加されていることも確認する)。 JARのルートから始まる絶対パスを使用する。 相対パスの使用:パスは呼び出しているクラスのパッケージディレクトリから始まる getResource/ getResoucreAsStream

と試してみてください。

Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")

の代わりに

Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")

(違いがあるかどうかはわかりませんが、前者は正しいClassLoader/ JARを使用しますが、後者はよくわかりません)

解説 (3)

このように、jarからリソースを取得するにはいくつかの方法があり、それぞれ微妙に異なる構文でパスを指定する必要があります。

私が見た中では、JavaWorldのこの記事が一番わかりやすい説明です。ここではその概要を紹介しますが、もっと詳しく知りたい方は記事をご覧ください。

メソッド

  1. ClassLoader.getResourceAsStream()

形式:"/"で区切られた名前、先行する"/"はない(すべての名前は絶対的なもの)。

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

  1. Class.getResourceAsStream()

フォーマット: "/"-分離された名前; 先頭の "/"は絶対名; その他の名前はクラス'のパッケージに対する相対名

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

解説 (3)