当前位置:  开发笔记 > 编程语言 > 正文

将文件加载为InputStream的不同方法

如何解决《将文件加载为InputStream的不同方法》经验,为你挑选了3个好方法。

有什么区别:

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中.



1> LordOfThePig..:

关于fileName你如何传递的解释存在微妙的差异.基本上,你有两种不同的方法:ClassLoader.getResourceAsStream()Class.getResourceAsStream().这两种方法将以不同方式定位资源.

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

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

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

在您的情况下,您从Application Server加载类,因此您应该使用Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName)而不是this.getClass().getClassLoader().getResourceAsStream(fileName).this.getClass().getResourceAsStream()也会工作.

阅读本文以获取有关该特定问题的更多详细信息.


警告Tomcat 7及更低版本的用户

这个问题的答案之一表明我对Tomcat 7的解释似乎不正确.我试图环顾四周,看看为什么会出现这种情况.

所以我看了Tomcat的WebAppClassLoader几个版本的Tomcat 的源代码.findResource(String name)在Tomcat 6和Tomcat 7中,实现(对于生成所请求资源的URL非常负责)实际上是相同的,但在Tomcat 8中是不同的.

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

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

因此,在使用ClassLoader.getResourceAsStream()Class.getResourceAsStream()早于8的Tomcat版本时,您必须格外小心.您还必须记住class.getResourceAsStream("/resource.txt")实际调用classLoader.getResourceAsStream("resource.txt")(前导/被剥离).


@BrianGordon:这使得它的行为与ClassLoader.getResourceAsStream()完全相同,因为后者将所有路径解释为绝对路径,无论它们是否以前导斜杠开头.因此,只要您的路径是绝对路径,两种方法的行为都相同.如果您的路径是相对的,那么行为就不同了.
我很确定`getClass().getResourceAsStream("/ myfile.txt")`与`getClassLoader().getResourceAsStream("/ myfile.txt")`的行为不同.

2> Tom Hawtin -..:

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

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



3> 小智..:

普通旧Java 7上的普通旧Java并没有其他依赖关系证明了它们的区别......

我把file.txtc:\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); 
  }
}

推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有