有什么区别:

InputStream is = this.getClass().getClassLoader().getResourceAsStream(fileName)

and

InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)

and

InputStream is = this.getClass().getResourceAsStream(fileName)

什么时候每一个都比其他的更适合使用?

我想要读取的文件在类路径中,作为读取该文件的类。我的类和文件在同一个jar中,打包在一个EAR文件中,并部署在WebSphere 6.1中。


当前回答

在普通的Java 7上使用普通的Java,没有其他依赖关系,这说明了区别……

我把file.txt放在c:\temp\中,然后把c:\temp\放在类路径中。

只有一种情况下,这两个调用之间有区别。

class J {

 public static void main(String[] a) {
    // as "absolute"

    // ok   
    System.err.println(J.class.getResourceAsStream("/file.txt") != null); 

    // pop            
    System.err.println(J.class.getClassLoader().getResourceAsStream("/file.txt") != null); 

    // as relative

    // ok
    System.err.println(J.class.getResourceAsStream("./file.txt") != null); 

    // ok
    System.err.println(J.class.getClassLoader().getResourceAsStream("./file.txt") != null); 

    // no path

    // ok
    System.err.println(J.class.getResourceAsStream("file.txt") != null); 

   // ok
   System.err.println(J.class.getClassLoader().getResourceAsStream("file.txt") != null); 
  }
}

其他回答

在普通的Java 7上使用普通的Java,没有其他依赖关系,这说明了区别……

我把file.txt放在c:\temp\中,然后把c:\temp\放在类路径中。

只有一种情况下,这两个调用之间有区别。

class J {

 public static void main(String[] a) {
    // as "absolute"

    // ok   
    System.err.println(J.class.getResourceAsStream("/file.txt") != null); 

    // pop            
    System.err.println(J.class.getClassLoader().getResourceAsStream("/file.txt") != null); 

    // as relative

    // ok
    System.err.println(J.class.getResourceAsStream("./file.txt") != null); 

    // ok
    System.err.println(J.class.getClassLoader().getResourceAsStream("./file.txt") != null); 

    // no path

    // ok
    System.err.println(J.class.getResourceAsStream("file.txt") != null); 

   // ok
   System.err.println(J.class.getClassLoader().getResourceAsStream("file.txt") != null); 
  }
}

使用MyClass.class.getClassLoader(). getresourceasstream (path)来加载与您的代码相关的资源。使用MyClass.class.getResourceAsStream(path)作为快捷方式,并用于打包在类包中的资源。

使用Thread.currentThread(). getcontextclassloader (). getresourceasstream (path)来获取属于客户端代码的资源,而不是与调用代码紧密绑定的资源。你应该小心这一点,因为线程上下文类装入器可能指向任何东西。

在尝试了一些加载文件的方法都没有成功之后,我想起来我可以使用FileInputStream,它工作得很好。

InputStream is = new FileInputStream("file.txt");

这是另一种将文件读入InputStream的方法,它从当前运行的文件夹中读取文件。

它起作用了,试试这个:

InputStream in_s1 =   TopBrandData.class.getResourceAsStream("/assets/TopBrands.xml");

这里所有这些答案,以及这个问题的答案,都建议加载绝对url,比如“/foo/bar”。class.getResourceAsStream(String)和class.getClassLoader(). getresourceasstream (String)处理相同。但事实并非如此,至少在我的Tomcat配置/版本(当前为7.0.40)中不是这样。

MyClass.class.getResourceAsStream("/foo/bar.properties"); // works!  
MyClass.class.getClassLoader().getResourceAsStream("/foo/bar.properties"); // does NOT work!

抱歉,我绝对没有令人满意的解释,但我猜tomcat对类加载器做了肮脏的把戏和他的黑魔法,导致了差异。我总是使用class.getResourceAsStream(String)在过去,没有任何问题。

PS:我也把这个贴在这里了