小编典典

getResourceAsStream() 与 FileInputStream

all

我试图在 webapp 中加载文件,FileNotFound当我使用FileInputStream.
但是,使用相同的路径,我能够在执行getResourceAsStream(). 这两种方法有什么区别,为什么一种有效而另一种无效?


阅读 60

收藏
2022-08-02

共1个答案

小编典典

and
consortsjava.io.File作用于本地磁盘文件系统。问题的根本原因是
相对
路径java.io依赖于当前工作目录。即JVM(在您的情况下:网络服务器的)启动的目录。例如,这可能是C:\Tomcat\bin或完全不同的东西,但因此
不是 C:\Tomcat\webapps\contextname或您期望的任何东西。在一个普通的 Eclipse
项目中,这将是C:\Eclipse\workspace\projectname. 您可以通过以下方式了解当前工作目录:

System.out.println(new File(".").getAbsolutePath());

但是,工作目录绝不是可编程控制的。您应该更喜欢在API 中使用
绝对File路径而不是相对路径。例如C:\full\path\to\file.ext

您不想硬编码或猜测 Java (web) 应用程序中的绝对路径。这只是可移植性问题(即它在系统 X 中运行,但不在系统 Y 中)。通常的做法是将这些资源放在
classpath 中,或者将其完整路径添加到 classpath 中(在像 Eclipse 这样的 IDE
中,src分别是文件夹和“构建路径”)。这样,您可以在ClassLoaderby
ClassLoader#getResource()或的帮助下抓住它们ClassLoader#getResourceAsStream()。正如您碰巧发现的那样,它能够定位相对于类路径的“根”的文件。在 web
应用程序(或任何其他使用多个类加载器的应用程序)中,建议使用ClassLoaderas
返回的Thread.currentThread().getContextClassLoader(),这样您也可以在 webapp 上下文“外部”查看。

webapps
中的另一种替代方法是ServletContext#getResource()及其对应的ServletContext#getResourceAsStream(). 它能够访问位于webwebapp 项目的公共文件夹中的文件,包括该/WEB- INF文件夹。ServletContext可以通过继承的方法在 servlet
中使用,getServletContext()您可以按原样调用它。

2022-08-02