私の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"
どちらもうまくいきません。 私は読んでたくさんいますこれまでのところ質問 は役に立ちませんでしたが、どれも役に立ちませんでした。私はすでに行っているルートパスを使用します。それか、単に現在のディレクトリからファイルをロードするだけです(単にfilename
をロードする)。これも私が試してみました。ファイルは適切な場所で適切な名前でJARにコンパイルされています。
どうやってこれを解決できますか?
Lifepaths.class.getClass().getResourceAsStream(...)
はシステムクラスローダを使ってリソースをロードしますが、JARが見えないので明らかに失敗します
Lifepaths.class.getResourceAsStream(...)
はLifepathsクラスをロードしたのと同じクラスローダーを使用してリソースをロードします。それはあなたのJAR内のリソースにアクセスできるはずです
規則は次のとおりです。
そして試してみてください。
Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")
の代わりに
Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")
(違いがあるかどうかはわかりませんが、前者は正しいClassLoader/JARを使用しますが、後者はわかりません)
そのため、jarからリソースを取得するにはいくつかの方法がありますが、それぞれパスの指定が異なる必要がある場合は構文が若干異なります。
私が見た最も良い説明は、 JavaWorld からのこの記事です。ここで要約しますが、もっと知りたいのなら記事をチェックしてください。
方法
1)ClassLoader.getResourceAsStream()
。
フォーマット:「/」で区切られた名前。先頭に "/"は付きません(すべての名前は絶対パスです)。
例:this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2)Class.getResourceAsStream()
フォーマット:「/」で区切られた名前。先頭の "/"は絶対名を示します。他のすべての名前はクラスのパッケージに関連しています
例:this.getClass().getResourceAsStream("/some/pkg/resource.properties");
絶対パスを使用しないでください。プロジェクト内の 'resources'ディレクトリを基準にしてください。ディレクトリ 'resources'にあるMyTest.txtの内容を表示する、すばやく汚いコード。
@Test
public void testDefaultResource() {
// can we see default resources
BufferedInputStream result = (BufferedInputStream)
Config.class.getClassLoader().getResourceAsStream("MyTest.txt");
byte [] b = new byte[256];
int val = 0;
String txt = null;
do {
try {
val = result.read(b);
if (val > 0) {
txt += new String(b, 0, val);
}
} catch (IOException e) {
e.printStackTrace();
}
} while (val > -1);
System.out.println(txt);
}
あなたは、ストリームを取得するためにこれを試してみたいかもしれません。すなわち、最初にURLを取得し、それからストリームとしてそれを開くことです。
URL url = getClass().getResource("/initialization/Lifepaths.txt");
InputStream strm = url.openStream();
私はかつて同じような質問をしました: jarからのtxtファイルの読み込みは失敗しますが、画像の読み込みはうまくいきます
あなたが使っているClassLoaderに問題があるようです。 contextClassLoaderを使用してクラスをロードします。これが静的メソッドか非静的メソッドかには関係ありません。
Thread.currentThread().getContextClassLoader().getResourceAsStream
......
助けになるかどうかわからないが、私の場合私のリソースは/ src /フォルダにあり、このエラーが出ていた。それから写真をbinフォルダに移動して問題を解決しました。
リソースディレクトリ(例: "src")がクラスパスにあることを確認してください(Eclipseのビルドパスのソースディレクトリになっていることを確認してください)。
Clazzがメインのクラスローダーからロードされていることを確認してください。
それから、src/initialization/Lifepaths.txtをロードするために、
clazz.getResourceAsStream("/initialization/Lifepaths.txt");
理由:clazz.getResourcesAsStream(foo)
はclazzのクラスパス内、clazzが存在するディレクトリからの相対パス _からfooを検索します。先頭に "/"を付けると、clazzのクラスパス内の任意のディレクトリのルートからロードされます。
Tomcatのようなある種のコンテナにいるのではないか、ClassLoaderで直接何かをしているのでない限り、あなたのEclipse /コマンドラインクラスパスを唯一のクラスローダクラスパスとして扱うことができます。
私は同じような問題に自分自身を見つけました。私はmavenを使っているので、pom.xmlを更新して次のようなものを含める必要がありました。
...
</dependencies>
<build>
<resources>
<resource>
<directory>/src/main/resources</directory>
</resource>
<resource>
<directory>../src/main/resources</directory>
</resource>
</resources>
<pluginManagement>
...
そこにあるリソースタグをメモして、そのフォルダがどこにあるかを指定します。ネストしたプロジェクトがある場合(私のように)、作業中のモジュール内ではなく、他の領域からリソースを入手したい場合があります。これは、同じリポジトリーデータを使用している場合、各リポジトリで同じファイルを保持する手間を省きます。
私の場合、ファイル名からスペースを削除しない限り、何も機能しませんでした。
私にとってうまくいったのは、My Project/Java Resources/srcにファイルを追加してから、
this.getClass().getClassLoader().getResourceAsStream(myfile.txt);
このファイルをパスに明示的に追加する必要はありません(/ srcに追加すると、明らかに行われます)。
デフォルトのJVMクラスローダーは、最初に親クラスローダーを使用してリソースをロードします。 。
Lifepaths.class.getClass()
のクラスローダーはbootstrap classloader
なので、getResourceAsStream
はユーザーが提供したclasspath
に関係なく、$ Java_HOMEのみを検索します。明らかに、Lifepaths.txtはありません。
Lifepaths.class
のクラスローダーはsystem classpath classloader
なので、getResourceAsStream
はユーザー定義のclasspath
を検索し、Lifepaths.txtがそこにあります。
Java.lang.Class#getResourceAsStream(String name)
を使用する場合、'/'で始まらない名前は、接頭辞としてpackage name
で追加されます。これを避けたい場合は、Java.lang.ClassLoader#getResourceAsStream
を使用してください。例えば:
ClassLoader loader = Thread.currentThread().getContextClassLoader();
String resourceName = "Lifepaths.txt";
InputStream resourceStream = loader.getResourceAsStream(resourceName);