Java getResourceAsStream 返回 null
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16570523/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
getResourceAsStream returns null
提问by
I'm loading a text file from within a package in a compiled JAR of my Java project. The relevant directory structure is as follows:
我正在从我的 Java 项目的已编译 JAR 中的包中加载文本文件。相关目录结构如下:
/src/initialization/Lifepaths.txt
My code loads a file by calling Class::getResourceAsStream
to return a InputStream
.
我的代码通过调用Class::getResourceAsStream
返回一个InputStream
.
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();}
}
The print out will always print null
, no matter what I use. I'm not sure why the above wouldn't work, so I've also tried:
null
无论我使用什么,打印出来的东西总是会打印出来。我不确定为什么上述方法不起作用,所以我也尝试过:
"/src/initialization/Lifepaths.txt"
"initialization/Lifepaths.txt"
"Lifepaths.txt"
"/src/initialization/Lifepaths.txt"
"initialization/Lifepaths.txt"
"Lifepaths.txt"
Neither of these work. I'vereadnumerousquestionsso far on the topic, but none of them have been helpful - usually, they just say to load files using the root path, which I'm already doing. That, or just load the file from the current directory (just load filename
), which I've also tried. The file is being compiled into the JAR in the appropriate location with the appropriate name.
这些都不起作用。我读了许多问题至今的话题,但他们都不是有帮助的-通常情况下,他们只是说,使用根路径,这我已经在做负载文件。那,或者只是从当前目录加载文件(只是 load filename
),我也试过。该文件正在被编译到具有适当名称的适当位置的 JAR 中。
How do I solve this?
我该如何解决这个问题?
采纳答案by hoaz
Lifepaths.class.getClass().getResourceAsStream(...)
loads resources using system class loader, it obviously fails because it does not see your JARs
Lifepaths.class.getClass().getResourceAsStream(...)
使用系统类加载器加载资源,它显然失败了,因为它没有看到你的 JAR
Lifepaths.class.getResourceAsStream(...)
loads resources using the same class loader that loaded Lifepaths class and it should have access to resources in your JARs
Lifepaths.class.getResourceAsStream(...)
使用加载 Lifepaths 类的相同类加载器加载资源,并且它应该可以访问 JAR 中的资源
回答by Puce
The rules are as follows:
规则如下:
- check the location of the file you want to load inside the JAR (and thus also make sure it actually added to the JAR)
- use either an absolute path: path starts at the root of the JAR
- use an relative path: path starts at the package directory of the class you're calling getResource/ getResoucreAsStream
- 检查要加载到 JAR 中的文件的位置(从而确保它确实添加到了 JAR 中)
- 使用绝对路径:路径从 JAR 的根开始
- 使用相对路径:路径从您调用的类的包目录开始 getResource/getResoucreAsStream
And try:
并尝试:
Lifepaths.class.getResourceAsStream("/initialization/Lifepaths.txt")
instead of
代替
Lifepaths.class.getClass().getResourceAsStream("/initialization/Lifepaths.txt")
(not sure if it makes a difference, but the former will use the correct ClassLoader/ JAR, while I'm not sure with the latter)
(不确定它是否有区别,但前者将使用正确的 ClassLoader/JAR,而我不确定后者)
回答by greedybuddha
So there are several ways to get a resource from a jar and each has slightly different syntax where the path needs to be specified differently.
因此,有多种方法可以从 jar 中获取资源,每种方法的语法略有不同,需要以不同方式指定路径。
The best explanation I have seen is this article from JavaWorld. I'll summarize here, but if you want to know more you should check out the article.
我见过的最好的解释是这篇来自JavaWorld 的文章。我会在这里总结一下,但如果你想了解更多,你应该看看这篇文章。
Methods
方法
1) ClassLoader.getResourceAsStream()
.
1)ClassLoader.getResourceAsStream()
。
Format: "/"-separated names; no leading "/" (all names are absolute).
格式:“/”-分隔的名称;没有前导“/”(所有名称都是绝对的)。
Example: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
例子: this.getClass().getClassLoader().getResourceAsStream("some/pkg/resource.properties");
2) Class.getResourceAsStream()
2) Class.getResourceAsStream()
Format: "/"-separated names; leading "/" indicates absolute names; all other names are relative to the class's package
格式:“/”-分隔的名称;前导“/”表示绝对名称;所有其他名称都相对于类的包
Example: this.getClass().getResourceAsStream("/some/pkg/resource.properties");
例子: this.getClass().getResourceAsStream("/some/pkg/resource.properties");
回答by MrD
You might want to try this to get the stream i.e first get the url and then open it as stream.
您可能想尝试使用此方法来获取流,即首先获取 url,然后将其作为流打开。
URL url = getClass().getResource("/initialization/Lifepaths.txt");
InputStream strm = url.openStream();
I once had a similar question: Reading txt file from jar fails but reading image works
我曾经有一个类似的问题:从 jar 读取 txt 文件失败,但读取图像有效
回答by Jain
@Emracool... I'd suggest you an alternative. Since you seem to be trying to load a *.txt file. Better to use FileInputStream()
rather then this annoying getClass().getClassLoader().getResourceAsStream()
or getClass().getResourceAsStream()
. At least your code will execute properly.
@Emracool ...我建议你另一种选择。由于您似乎正在尝试加载 *.txt 文件。最好使用FileInputStream()
而不是这个烦人的getClass().getClassLoader().getResourceAsStream()
或getClass().getResourceAsStream()
. 至少你的代码会正确执行。
回答by Paul Smith
Don't use absolute paths, make them relative to the 'resources' directory in your project. Quick and dirty code that displays the contents of MyTest.txt from the directory '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);
}
回答by Leo Ufimtsev
Don't know if of help, but in my case I had my resource in the /src/ folder and was getting this error. I then moved the picture to the bin folder and it fixed the issue.
不知道是否有帮助,但就我而言,我的资源位于 /src/ 文件夹中,但出现此错误。然后我将图片移动到 bin 文件夹并解决了问题。
回答by Bobby Martin
Make sure your resource directory (e.g. "src") is in your classpath (make sure it's a source directory in your build path in eclipse).
确保您的资源目录(例如“src”)在您的类路径中(确保它是 eclipse 中构建路径中的源目录)。
Make sure clazz is loaded from the main classloader.
确保从主类加载器加载 clazz。
Then, to load src/initialization/Lifepaths.txt, use
然后,要加载 src/initialization/Lifepaths.txt,请使用
clazz.getResourceAsStream("/initialization/Lifepaths.txt");
Why:
clazz.getResourcesAsStream(foo)
looks up foo from within the classpath of clazz, relative to the directory clazz lives in. The leading "/" makes it load from the root of any directory in the classpath of clazz.
为什么:
clazz.getResourcesAsStream(foo)
从clazz 的类路径中查找 foo ,相对于 clazz 所在的目录。前导“/”使其从 clazz 类路径中任何目录的根目录加载。
Unless you're in a container of some kind, like Tomcat, or are doing something with ClassLoaders directly, you can just treat your eclipse/command line classpath as the only classloader classpath.
除非您在某种容器中,例如 Tomcat,或者直接使用 ClassLoaders 执行某些操作,否则您可以将 eclipse/命令行类路径视为唯一的类加载器类路径。
回答by Binita Bharati
There seems to be issue with the ClassLoader that you are using. Use the contextClassLoader to load class. This is irrespective of whether it is in a static/non-static method
您使用的 ClassLoader 似乎存在问题。使用 contextClassLoader 加载类。这与是否在静态/非静态方法中无关
Thread.currentThread().getContextClassLoader().getResourceAsStream
......
Thread.currentThread().getContextClassLoader().getResourceAsStream
......
回答by CommonCoreTawan
What worked for me was to add the file under My Project/Java Resources/src
and then use
对我My Project/Java Resources/src
有用的是在下面添加文件然后使用
this.getClass().getClassLoader().getResourceAsStream("myfile.txt");
I didn't need to explicitly add this file to the path (adding it to /src
does that apparently)
我不需要将此文件显式添加到路径中(将它添加到/src
显然是这样做的)