getResourceAsStream() 与 FileInputStream [英] getResourceAsStream() vs FileInputStream
问题描述
我试图在 Web 应用程序中加载文件,但在使用 FileInputStream
时遇到了 FileNotFound
异常.但是,使用相同的路径,我可以在执行 getResourceAsStream()
时加载文件.这两种方法有什么区别,为什么一种有效而另一种无效?
I was trying to load a file in a webapp, and I was getting a FileNotFound
exception when I used FileInputStream
. However, using the same path, I was able to load the file when I did getResourceAsStream()
.
What is the difference between the two methods, and why does one work while the other doesn't?
推荐答案
java.io.File
和 consorts 作用于本地磁盘文件系统.问题的根本原因是 java.io
中的 relative 路径依赖于当前工作目录.IE.JVM(在您的情况下:网络服务器的)启动的目录.例如,这可能是 C:\Tomcat\bin
或完全不同的东西,但因此 不是 C:\Tomcat\webapps\contextname
或其他任何东西你会期望它是.在普通的 Eclipse 项目中,这将是 C:\Eclipse\workspace\projectname
.您可以通过以下方式了解当前工作目录:
The java.io.File
and consorts acts on the local disk file system. The root cause of your problem is that relative paths in java.io
are dependent on the current working directory. I.e. the directory from which the JVM (in your case: the webserver's one) is started. This may for example be C:\Tomcat\bin
or something entirely different, but thus not C:\Tomcat\webapps\contextname
or whatever you'd expect it to be. In a normal Eclipse project, that would be C:\Eclipse\workspace\projectname
. You can learn about the current working directory the following way:
System.out.println(new File(".").getAbsolutePath());
然而,工作目录绝不是可编程控制的.您真的应该更喜欢在 File
API 中使用 绝对 路径而不是相对路径.例如.C:\full\path\to\file.ext
.
However, the working directory is in no way programmatically controllable. You should really prefer using absolute paths in the File
API instead of relative paths. E.g. C:\full\path\to\file.ext
.
您不想硬编码或猜测 Java (web) 应用程序中的绝对路径.那只是可移植性问题(即它在系统 X 中运行,但不在系统 Y 中运行).通常的做法是将这些资源放在 classpath 中,或者将其完整路径添加到类路径中(在 Eclipse 之类的 IDE 中,它是 src
文件夹和 "构建路径").通过这种方式,您可以通过 ClassLoader#getResource()
或 ClassLoader#getResourceAsStream()
.它能够定位相对于根"目录的文件.的类路径,正如您偶然发现的那样.在 web 应用程序(或任何其他使用多个类加载器的应用程序)中,建议使用 Thread.currentThread().getContextClassLoader()
返回的 ClassLoader
用于此目的,以便您可以查看外面"Web 应用上下文也是如此.
You don't want to hardcode or guess the absolute path in Java (web)applications. That's only portability trouble (i.e. it runs in system X, but not in system Y). The normal practice is to place those kind of resources in the classpath, or to add its full path to the classpath (in an IDE like Eclipse that's the src
folder and the "build path" respectively). This way you can grab them with help of the ClassLoader
by ClassLoader#getResource()
or ClassLoader#getResourceAsStream()
. It is able to locate files relative to the "root" of the classpath, as you by coincidence figured out. In webapplications (or any other application which uses multiple classloaders) it's recommend to use the ClassLoader
as returned by Thread.currentThread().getContextClassLoader()
for this so you can look "outside" the webapp context as well.
webapps 中的另一种选择是 ServletContext#getResource()
及其对应物 ServletContext#getResourceAsStream()
.它能够访问位于 webapp 项目的公共 web
文件夹中的文件,包括 /WEB-INF
文件夹.ServletContext
通过继承的 getServletContext()
方法,可以直接调用.
Another alternative in webapps is the ServletContext#getResource()
and its counterpart ServletContext#getResourceAsStream()
. It is able to access files located in the public web
folder of the webapp project, including the /WEB-INF
folder. The ServletContext
is available in servlets by the inherited getServletContext()
method, you can call it as-is.
- 在基于 servlet 的应用程序中,在哪里放置以及如何读取配置资源文件?
- servletcontext.getRealPath("/") 意思是我应该什么时候使用它
- 在 servlet 中保存上传文件的推荐方式申请
- 如何保存生成的文件暂时在基于 servlet 的 Web 应用程序中
这篇关于getResourceAsStream() 与 FileInputStream的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!