Java getClassLoader().getResourceAsStream(文件名)

Java getClassLoader().getResourceAsStream(filename)

我有一个 Maven 项目。我的全部代码都在文件夹 {PROJECT_ROOT}/src/main/java 中。当我写代码时:

InputStream input = VertxApp.class.getClassLoader().getResourceAsStream("file.txt");
String result = getStringFromInputStream(input);
System.out.println(result);

我看到代码在文件夹中查找名为 "file.txt" 的文件: {PROJECT_ROOT}/src/main/resources。

我的问题是为什么。例如,为什么它不在 {PROJECT_ROOT}/src/main/java 或 ${PROJECT_ROOT} 中查找文件?

大多数 Maven 项目都遵循

的结构
src/
  main/
    java/
    resources/

您打算将非代码资源与代码分开。 getResourceAsStream 方法假定遵循此标准,因此它会从 resources/ 目录开始查找您的资源。

有关更详细的想法,请参阅 Why are project layout resources are kept separate from Java sources?

当您从支持 Maven 的 IDE 构建 Maven 项目或 运行 它时,来自 src/main/java 的 java 文件被编译为 class 文件并输入 PROJECT_ROOT/target/classes

来自 src/main/resources 的文件也被复制到 PROJECT_ROOT/target/classes

当您调用 VertxApp.class.getClassLoader().getResourceAsStream("file.txt") 时,您会得到 VertxApp class 的 classloader 并且此 classloader 将尝试从中加载给定资源class 的加载路径。

如果您的 VertxAppclass 在顶层包中,class 文件将在 target/classes 中,并且资源会像您一样被搜索指定 "file.txt" 的相对路径,因此必须将其放在 src/main/resources.

例如,如果 VertxAppclass 在名为 mypackage 的包中,那么 class 文件将在 target/classes/mypackage 中,您应该拥有文件在 src/main/resources/mypackage 中,这样它最终也会在 target/classes/mypackage 中。

如果你在包中有 VertxAppclass 但想将文件保留在 src/main/resources 中(没有子目录),你必须像这样将其作为绝对路径引用:

VertxApp.class.getClassLoader().getResourceAsStream("/file.txt")