在高中短暂学习 Java 后,我正在重新审视 Java,以完成 lwjgl git book 。有一个部分让我有点迷失,其中应该使用函数“getResourceAsStream”加载片段着色器/顶点着色器。
我尝试了不同的方法,并徒劳地尝试调试/打印 JVM 搜索文件的位置,但我有点不知所措。我很困惑,但也更愿意了解为什么这段代码在我的机器上不起作用,以及如何让它工作(使用这种包/类加载方法)。
由于这些类共享“主”类,我认为 JVM 会从那里开始搜索“资源”文件夹。但事实似乎并非如此。
我确实认为这与包声明有关,但我还不够理解,无法继续。
以下是相关文件和位置...我尝试只包含我认为重要的内容。
// project-root/src/main/java/org/lwjglb/engine/Utils.java
package main.java.org.lwjglb.engine;
// other imports...
public class Utils {
public static String loadResource(String fileName) {
InputStream in = class.forName(Utils.class.getName()).getResourceAsStream(fileName);
// 'in' is null after this call
// other code...
}
}
// project-root/src/main/java/org/lwjglb/game/Renderer.java
import main.java.org.lwjgl.engine.Utils;
// other imports...
public class Renderer {
public void init() {
Utils.loadResource("/vertex.vs"); // fails
}
}
// project-root/src/main/resources/vertex.vs
// vertex shader code...
问题在于 getResourceAsStream() 调用返回 null,因此依赖于有效结果的以下代码会崩溃并出现 java.lang.NullPointerException。
我应该向 getResourceAsStream() 传递什么路径才能使其不返回 null?
最佳答案
假设以下目录结构:
|-- src
`-- test
|-- java
| `-- shaders
| `-- ShaderParser.java
`-- resources
`-- shaders
`-- fragmentShader.txt
从“ShaderParser.java”获取资源“fragmentShader.txt”的正确方法是:
Class clazz = Class.forName(TestUtils.class.getName());
InputStream in = clazz.getResourceAsStream("../../resources/shaders/fragmentShader.txt");
../
意思是“向上遍历一个目录”。
该路径从 src/test/java/shaders/
开始目录,所以我们使用 ../../
向上遍历两次进入 src/test/
然后继续我们剩下的道路resources/shaders/fragmentShader.txt
.
重要的是要记住,当使用 Class#getResourceAsStream() 时,它使用类所在的包作为基目录。它仅使用相对路径,因为它尝试使用该类加载资源'ClassLoader 。如果提供了完全限定的路径或从项目根目录开始的路径,则该路径将不起作用。
请引用documentation了解更多信息。
关于java - Java getResourceAsStream 出现问题,对包的工作方式感到困惑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56230865/