我试图在 web 应用程序中加载文件,当我使用 FileInputStream
时遇到 FileNotFound
异常。但是,使用相同的路径,当我执行 getResourceAsStream()
时,我能够加载文件。
这两种方法有什么区别,为什么一种有效而另一种无效?
最佳答案
java.io.File
和 consorts 作用于本地磁盘文件系统。问题的根本原因是 java.io
中的 relative 路径依赖于当前工作目录。 IE。 JVM(在您的情况下:网络服务器的)启动的目录。例如,这可能是 C:\Tomcat\bin
或完全不同的东西,但因此 not C:\Tomcat\webapps\contextname
或其他你会期望它是。在一个普通的 Eclipse 项目中,应该是 C:\Eclipse\workspace\projectname
。您可以通过以下方式了解当前工作目录:
System.out.println(new File(".").getAbsolutePath());
但是,工作目录绝不是可编程控制的。您应该更喜欢在 File
API 中使用 absolute 路径而不是相对路径。例如。 C:\full\path\to\file.ext
.
您不想硬编码或猜测 Java(Web)应用程序中的绝对路径。这只是可移植性问题(即它在系统 X 中运行,但不在系统 Y 中)。通常的做法是将这些资源放在 classpath 中,或者将其完整路径添加到 classpath(在像 Eclipse 这样的 IDE 中,即 src
文件夹和“构建路径”)。这样你就可以在 ClassLoader
by ClassLoader#getResource()
的帮助下抓取它们。或 ClassLoader#getResourceAsStream()
.正如您碰巧发现的那样,它能够定位相对于类路径的“根”的文件。在 web 应用程序(或任何其他使用多个类加载器的应用程序)中,建议使用 Thread.currentThread().getContextClassLoader()
返回的 ClassLoader
以便您可以查看“在”webapp 上下文之外。
webapps 中的另一种选择是 ServletContext#getResource()
及其对应的ServletContext#getResourceAsStream()
.它能够访问位于 webapp 项目的公共(public) web
文件夹中的文件,包括 /WEB-INF
文件夹。 ServletContext
可通过继承的 getServletContext()
在 servlet 中使用。方法,您可以按原样调用它。
另见:
关于java - getResourceAsStream() 与 FileInputStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2308188/