在如何解释您传递的fileName方面存在微妙的差异。基本上,你有2个不同的方法:ClassLoader.getResourceAsStream()和Class.getResourceAsStream()。这两种方法将以不同的方式定位资源。
In Class.getResourceAsStream(path), the path is interpreted as a path local to the package of the class you are calling it from. For example calling, String.class.getResourceAsStream("myfile.txt") will look for a file in your classpath at the following location: "java/lang/myfile.txt". If your path starts with a /, then it will be considered an absolute path, and will start searching from the root of the classpath. So calling String.class.getResourceAsStream("/myfile.txt") will look at the following location in your class path ./myfile.txt.
getresourceasstream (path)将认为所有路径都是绝对路径。因此调用String.class.getClassLoader(). getresourceasstream ("myfile.txt")和String.class.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的WebAppClassLoader的几个版本的源代码。findResource(字符串名称)的实现(最终负责生成请求资源的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")(前导/被去掉)。