181

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

4

6 回答 6

260

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()您可以按原样调用它。

也可以看看:

于 2010-02-22T01:59:29.290 回答
28

getResourceAsStream是为 Web 应用程序执行此操作的正确方法(正如您已经了解的那样)。

原因是如果您将 Web 应用程序打包到 WAR 中,则无法从文件系统读取。这是打包 Web 应用程序的正确方法。这种方式是可移植的,因为您不依赖于绝对文件路径或应用服务器的安装位置。

于 2010-02-22T01:03:13.320 回答
15

FileInputStream 将加载您传递给构造函数的文件路径,作为Java 进程工作目录的相对路径。通常在 Web 容器中,这类似于bin文件夹。

getResourceAsStream()将从应用程序的 classpath加载相对文件路径。

于 2010-02-22T00:57:14.890 回答
13

该类FileInputStream直接与底层文件系统一起工作。如果有问题的文件实际上不存在于那里,它将无法打开它。该getResourceAsStream()方法的工作方式不同。它尝试使用ClassLoader调用它的类来定位和加载资源。例如,这使其能够查找嵌入到jar文件中的资源。

于 2010-02-22T00:57:59.437 回答
8

classname.getResourceAsStream() 通过类名的类加载器加载文件。如果该类来自一个 jar 文件,那么这就是加载资源的地方。

FileInputStream 用于从文件系统中读取文件。

于 2010-02-22T00:59:47.500 回答
1

我在这里通过将它们标记为文件读取(java.io)和资源读取(ClassLoader.getResourceAsStream())来分离这两种用法。

文件读取 - 1. 适用于本地文件系统。2. 尝试将当前 JVM 启动目录请求的文件定位为 root 3. 理想情况下使用文件在预先确定的位置(如 /dev/files 或 C:\Data)进行处理。

资源读取 - 1. 在类路径上工作 2. 尝试在当前或父类加载器类路径中定位文件/资源​​。3. 尝试从打包文件(如 war 或 jar)加载文件时非常理想。

于 2019-01-16T10:50:47.123 回答