我正在从我的Java项目的编译JAR中的包中加载一个文本文件。相关目录结构如下:

/src/initialization/Lifepaths.txt

我的代码通过调用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();}
}

不管我用什么,输出总是输出null。我不知道为什么上面的方法不管用,所以我也尝试了一下:

“初始化/ src / / Lifepaths.txt” “初始化/ Lifepaths.txt” “Lifepaths.txt”

这两种方法都不起作用。到目前为止,我已经阅读了许多关于这个主题的问题,但没有一个是有帮助的——通常,他们只是说使用根路径加载文件,而我已经这样做了。或者只是从当前目录加载文件(只是加载文件名),我也尝试过。该文件将被编译到JAR中的适当位置,并具有适当的名称。

我怎么解决这个问题?


当前回答

jdk >=9 needs to open non-root/non-co-parent packages to it in the module-info module.

JDK >=9需要在module-info.java中打开资源目录,例如:

src java resoureces 相依 json log4j2.xml openapi.yaml

如果需要读取conf/config。Json,你需要两个步骤:

// in module-info.java
module your.mod.name {
    open conf;
}

// then in java code
getClassLoader().getResourceAsStream("conf/config.json");

否则,如果你需要在根目录下读取other,它只是:

getClassLoader().getResourceAsStream("openapi.yaml");

你可以看到{@link java.lang.ClassLoader#getResourceAsStream(String)}知道为什么~

其他回答

确保您的资源目录(例如:"src")在类路径中(确保它是eclipse中构建路径中的源目录)。

确保clazz是从主类加载器加载的。

然后,加载src/initialization/Lifepaths.txt,使用

clazz.getResourceAsStream("/initialization/Lifepaths.txt");

原因: getresourcesasstream (foo)从clazz的类路径中查找foo,相对于clazz所在的目录。前导的“/”使它从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>
        ...

请注意其中的资源标记,以指定文件夹的位置。如果你有嵌套的项目(像我一样),那么你可能想从其他领域获得资源,而不仅仅是在你工作的模块中。如果您使用类似的配置数据,这有助于减少在每次回购中保持相同的文件

如果您正在使用IDEA,请确保将您的资源文件夹标记为“resources”,以便IDE可以正确识别该路径。

假设你有一个名为book的文件。Json在resources/中,然后使用其中的资源,你可以这样做

InputStream input = Main.class.getResourceAsStream("/book.json");

jdk >=9 needs to open non-root/non-co-parent packages to it in the module-info module.

JDK >=9需要在module-info.java中打开资源目录,例如:

src java resoureces 相依 json log4j2.xml openapi.yaml

如果需要读取conf/config。Json,你需要两个步骤:

// in module-info.java
module your.mod.name {
    open conf;
}

// then in java code
getClassLoader().getResourceAsStream("conf/config.json");

否则,如果你需要在根目录下读取other,它只是:

getClassLoader().getResourceAsStream("openapi.yaml");

你可以看到{@link java.lang.ClassLoader#getResourceAsStream(String)}知道为什么~

你正在使用的ClassLoader似乎有问题。使用contextClassLoader加载类。这与它是静态方法还是非静态方法无关

.getContextClassLoader Thread.currentThread () () .getResourceAsStream……