getResourceAsStream()vs FileInputStream

时间:2010-02-22 00:52:39

标签: java file-io web-applications fileinputstream

我正在尝试在webapp中加载文件,当我使用FileNotFound时,我收到FileInputStream例外。但是,使用相同的路径,我能够在getResourceAsStream()时加载文件。 这两种方法之间有什么区别,为什么一种方法有效而另一方方法无效?

6 个答案:

答案 0 :(得分:253)

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

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

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

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

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

另见:

答案 1 :(得分:26)

getResourceAsStream是为网络应用做的正确方法(正如您已经了解的那样)。

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

答案 2 :(得分:13)

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

getResourceAsStream()将加载相对from your application's classpath的文件路径。

答案 3 :(得分:12)

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

答案 4 :(得分:6)

classname.getResourceAsStream()通过classname的类加载器加载文件。如果该类来自jar文件,那么将从中加载资源。

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

答案 5 :(得分:0)

我在这里通过将这两种用法标记为File Read(java.io)和Resource Read(ClassLoader.getResourceAsStream())来分开使用。

文件读取- 1.在本地文件系统上工作。 2.尝试以root用户身份找到当前JVM启动目录中请求的文件 3.使用文件在预定位置(例如/ dev / files或C:\ Data)进行处理时,非常理想。

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