getresourceasstream()与fileinputstream

093gszye  于 2021-07-12  发布在  Java
关注(0)|答案(6)|浏览(414)

我试着在一个网络应用程序中加载一个文件,我得到了一个 FileNotFound 当我使用 FileInputStream . 但是,使用相同的路径,我可以加载文件时,我这样做了 getResourceAsStream() . 这两种方法有什么区别,为什么一种有效而另一种无效?

bwleehnv

bwleehnv1#

这个 java.io.File 和consorts作用于本地磁盘文件系统。问题的根本原因是 java.io 依赖于当前工作目录。i、 e.启动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)应用程序中的绝对路径。这是唯一的可移植性问题(即它在systemx中运行,但在systemy中不运行)。通常的做法是将这些资源放在类路径中,或者将其完整路径添加到类路径中(在像eclipse这样的ide中,这是 src 文件夹和“构建路径”。这样,你就可以抓住他们的帮助下 ClassLoaderClassLoader#getResource() 或者 ClassLoader#getResourceAsStream() . 它能够相对于类路径的“根”定位文件,正如您碰巧发现的那样。在webapplications(或任何其他使用多个类加载器的应用程序)中,建议使用 ClassLoader 由返回 Thread.currentThread().getContextClassLoader() 因此,您也可以查看“外部”webapp上下文。
webapps的另一个选择是 ServletContext#getResource() 以及它的对应物 ServletContext#getResourceAsStream() . 它能够访问位于公共区域的文件 web webapp项目的文件夹,包括 /WEB-INF 文件夹。这个 ServletContext 在servlet中由继承的 getServletContext() 方法,可以按原样调用它。

另请参见:

在基于servlet的应用程序中,在何处放置配置资源文件以及如何读取配置资源文件?
servletcontext.getrealpath(“/”)是什么意思?我应该在什么时候使用它
在servlet应用程序中保存上载文件的推荐方法
如何在基于servlet的web应用程序中临时保存生成的文件

pw136qt2

pw136qt22#

getResourceAsStream 对于web应用程序来说,这是正确的方法(正如您已经学到的)。
原因是,如果你在战争中打包你的web应用程序,那么从文件系统读取数据就无法工作。这是打包web应用程序的正确方法。这种方式是可移植的,因为您不依赖于绝对文件路径或安装应用服务器的位置。

yr9zkbsy

yr9zkbsy3#

fileinputstream将从java进程的工作目录中加载一个文件路径,该路径作为相对路径传递给构造函数。通常在web容器中,这类似于 bin 文件夹。 getResourceAsStream() 将从应用程序的类路径加载相对的文件路径。

bxjv4tth

bxjv4tth4#

这个 FileInputStream 类直接与底层文件系统一起工作。如果有问题的文件实际不在那里,它将无法打开它。这个 getResourceAsStream() 方法的工作原理不同。它尝试使用 ClassLoader 它被召唤的班级。这使得它能够找到,例如,嵌入到 jar 文件夹。

cwdobuhd

cwdobuhd5#

getresourceasstream()通过classname的类加载器加载文件。如果类来自jar文件,则资源将从该文件加载。
fileinputstream用于从文件系统读取文件。

rseugnpd

rseugnpd6#

我在这里通过将它们标记为文件读取(java.io)和资源读取(classloader.getresourceasstream())来区分这两种用法。
文件读取-1。在本地文件系统上工作。2.尝试将从当前jvm启动目录请求的文件定位为根3。理想情况下,使用文件在预先确定的位置(如/dev/files或c:\data)进行处理时效果良好。
资源读取-1。在类路径2上工作。尝试在当前或父类加载器类路径中定位文件/资源。3.在尝试从打包文件(如war或jar)加载文件时非常理想。

相关问题