将文件作为InputStream加载的不同方式

有什么区别:

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

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

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

什么时候比其他人更适合使用?

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


关于您传递的fileName如何解释有细微的差异。 基本上,你有2种不同的方法: ClassLoader.getResourceAsStream()Class.getResourceAsStream() 。 这两种方法将以不同方式查找资源。

Class.getResourceAsStream(path) ,该路径被解释为本地到您调用它的类的包的路径。 例如调用, String.getResourceAsStream("myfile.txt")将在以下位置的类路径中查找文件: "java/lang/myfile.txt" 。 如果你的路径以/开始,那么它将被视为绝对路径,并且将从类路径的根开始搜索。 因此,调用String.getResourceAsStream("/myfile.txt")将查看类路径./myfile.txt中的以下位置。

ClassLoader.getResourceAsStream(path)将所有路径视为绝对路径。 因此,调用String.getClassLoader().getResourceAsStream("myfile.txt")String.getClassLoader().getResourceAsStream("/myfile.txt")将在以下位置的类路径中查找文件: ./myfile.txt

每次我在这篇文章中提到一个位置时,它都可能是文件系统本身的一个位置,或者位于相应的jar文件中,具体取决于您要从中加载资源的Class和/或ClassLoader。

在你的情况下,你从应用服务器加载类,所以你应该使用Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)而不是this.getClass().getClassLoader().getResourceAsStream(fileName)this.getClass().getResourceAsStream()也可以。

阅读这篇文章,了解有关该特定问题的更多详细信息。


警告Tomcat 7及以下用户

这个问题的答案之一指出,我的解释似乎是不正确的Tomcat 7.我试图环顾四周,看看为什么会这样。

所以我查看了Tomcat的几个版本Tomcat的WebAppClassLoader的源代码。 findResource(String name) (它完全负责生成所请求资源的URL)的实现在Tomcat 6和Tomcat 7中几乎相同,但在Tomcat 8中不同。

在版本6和7中,实现不会尝试标准化资源名称。 这意味着在这些版本中, classLoader.getResourceAsStream("/resource.txt")可能不会产生与classLoader.getResourceAsStream("resource.txt")事件相同的结果,尽管它应该(因为Javadoc指定的)。 [源代码]

但是,在版本8中,资源名称被标准化以确保资源名称的绝对版本是使用的资源名称。 因此,在Tomcat 8中,上述两个调用应始终返回相同的结果。 [源代码]

因此,在8以前的Tomcat版本上使用ClassLoader.getResourceAsStream()Class.getResourceAsStream()时,必须特别小心。并且还必须记住, class.getResourceAsStream("/resource.txt")实际上调用classLoader.getResourceAsStream("resource.txt") (领先的/被剥离)。


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

使用Thread.currentThread().getContextClassLoader().getResourceAsStream(path)来获取作为客户端代码一部分的资源,而不是紧挨调用代码。 你应该小心,因为线程上下文类加载器可以指向任何东西。


普通的旧Java 7上的普通旧式Java,并且没有其他依赖关系证明它们之间的区别...

我把c:temp file.txt放在classpath中,并把c:temp放在classpath中。

只有一种情况是两个电话之间有区别。

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); 
  }
}
链接地址: http://www.djcxy.com/p/78369.html

上一篇: Different ways of loading a file as an InputStream

下一篇: How do I convert an InputStream to a String in Java?