【问题标题】:Using getResourceAsStream is not working in Java [duplicate]使用 getResourceAsStream 在 Java 中不起作用 [重复]
【发布时间】:2016-03-04 13:25:30
【问题描述】:

我有一个非常简单的方法,它使用getclass().getResourceAsStream() 方法来读取文件。但是它总是返回 null,我不知道出了什么问题。这是我的一段代码。

InputStream sw = getClass().getResourceAsStream("/filename.txt");
BufferedReader bf = new BufferedReader( new InputStreamReader(sw));

sw 始终保持为空。文件filename.txt 存在于我项目的根目录中。

编辑: 我找到了原因。我意识到我正在从 Eclipse 运行我的项目,并且该项目不是我 PC 上类路径的一部分。但是,如果我将程序打包为 jar 文件然后运行它,则 jar 文件中的文件被视为资源,可以使用 getResourceAsStream() 方法读取。

【问题讨论】:

  • /filename.txt 是绝对路径。 ./filename.txt 有效吗?
  • 定义“你的项目的根目录”。它在类路径上吗?
  • @Ivan:不,它也不工作。
  • @DaveNewton:不,不是,我不想成为。因为我要做的是在 hadoop 工作中使用这段代码。这有助于我将每个依赖项打包到我的 jar 文件中,然后发布。在 HAdoop 中,jar 文件被复制的地方并不总是在类路径中
  • 在提问之前您是否检查了How to really read text file from classpath in Java 或与getResourcesAsStream 相关的任何其他问题?

标签: java


【解决方案1】:

Class.getResourceAsStream() 方法在 Java 类路径中查找指定资源,而不是基于项目根目录。

项目根目录通常不是类路径的一部分。相反,您应该有一个 src 文件夹(或类似名称),其中包含 Java 文件,也可能包含您的文本文件。或者,如果您使用 Maven,您有文件夹 src/main/javasrc/main/resources,它们是类路径根。在这种情况下,文本文件应位于资源文件夹中。

如果您的项目被打包到.jar 文件中,则它的所有资源都会与 .class 文件一起打包在 .jar 文件中,并且可以通过 Class.getResourceAsStream() 找到。

【讨论】:

  • 大多数构建系统会将中间构建文件(如 .class 文件)复制到 build 目录,因此它可能有助于 OP 查找那里。 OP 期望的所有文件都在吗?
【解决方案2】:

从 ClassLoader 的角度来看,您的项目的根目录并不总是路径的根目录。 找出它试图从哪里加载资源的最简单方法:

System.out.println(MyClass.class.getResource("/").getPath());

之后,您可能能够轻松找出导致您的假设与文件正确放置的现实之间存在差异的项目部分或运行配置。

【讨论】:

  • 是的,我没有尝试过...:) 抱歉,已修复... :)
  • 你试过这个吗? / 也不是资源...
  • 好点。 OP 可以尝试类似System.out.println(MyClass.getClass().getResource(MyClass.class.getName().replace('.','/')).getPath());(未测试)。
  • Tobias:我做到了,在 Eclipse 中它给了我以下信息:/C:/Users/username/workspace/project/bin/
  • @pifta 是的,它需要那些修改或类似的东西,我有点搞砸了。类加载很复杂!
【解决方案3】:

getResourceAsStream() 读取一个资源文件,即一个文件到.jar 文件(或资源目录)中,而不是磁盘上工作目录中的常规文件。使用 FileReader 从磁盘读取文件

【讨论】:

  • 如果程序不是在 Jar 文件中运行,那么类加载器会在文件系统中搜索 .class 文件(以及像 filename.txt 这样的资源)。
  • 没错,我是从 Eclipse 运行程序,但我的目标是将它打包成 jar 文件然后运行。
【解决方案4】:

同样是用户,

InputStream sw = this.class.getClassLoader().getResourceAsStream("filename.txt");

注意:文件名.txt 文件应该存在于类路径中。

【讨论】:

    【解决方案5】:

    为了完整起见,这里有一个简单的测试,可以打印出资源的绝对路径。您可以在任何类中使用它来查找该类在硬盘驱动器上的位置,以防您的构建系统在做什么并不明显。只需将名称 ErrorTest 替换为您正在检查的课程即可。

    public class ErrorTest
    {
       public static void main(String[] args )
       {
          final String className = ErrorTest.class.getSimpleName().replace( '.', '/').concat(".class");
          System.out.println(ErrorTest.class.getResource(className).getPath() );
       }
    }
    

    这个程序的输出:

    run:
    /C:/Users/Brenden/Google%20Drive/proj/tempj8/build/classes/quicktest/ErrorTest.class
    BUILD SUCCESSFUL (total time: 0 seconds)
    

    【讨论】:

      猜你喜欢
      • 2012-10-05
      • 1970-01-01
      • 1970-01-01
      • 2014-05-15
      • 1970-01-01
      • 1970-01-01
      • 2016-06-24
      • 2015-07-19
      • 2015-08-22
      相关资源
      最近更新 更多