getResourceAsStream("Words.txt") 和 FileInputStream("./src/package/Words.txt") 有什么区别?

What is the difference between getResourceAsStream("Words.txt") and FileInputStream("./src/package/Words.txt")?

我目前正在编写一个基于 servlet 的应用程序(客户端)。我试图在代码所在的同一个包中获取一个文本文件。我遇到的所有方法都使用 MyClass.class.getResourceAsStream("Words.txt")classLoader.getResourceAsStream("Words.txt") 来获取文本文件(例如:SO1, SO2)。但是我已经试过了FileInputStream("./src/package/Words.txt"),文本文件还是可以成功加载。

有什么区别?为什么 getResourceAsStream 鼓励这种方法?

此刻,您在您的开发人员工作站上,并且可能正在从您的 IDE 中 运行 安装您的应用程序。 Tomcat恰好是从IDE项目根目录启动的,因此使用

new FileInputStream("./src/package/Words.txt")

允许读取存储在项目 src 目录中的文件。

但这不是项目在生产中 运行 的样子。在生产中,您将使用 shell 脚本从完全不同的目录启动一个 Tomcat 服务器。而生产服务器根本不会有源项目。它只有 Tomcat,以及 war 文件构成从项目构建的工件。

所以根本不会有 src 目录,文件 Words.txt 甚至不会出现在文件系统的任何地方。它只会是 war 文件(实际上是一个 zip 文件)的入口,位于 WEB-INF/classes/package 下,连同编译器从 [=41= 生成的 .class 文件] 源文件。

因此,为了能够读取 "file",您不能使用文件 IO:文件系统中不存在 "file"。您需要使用 ClassLoader,它将在 war 文件中找到 "file" 并从那里加载它。

这在开发过程中也很顺利,当应用程序是 运行 来自分解的 war 结构时:class 加载程序将在目标下找到 class IDE 用于存储 class 文件和资源文件的目录。

请注意,如果资源在包 com.foo 中并且 MyClass 在同一个包中,则加载该资源所需的是

MyClass.class.getResourceAsStream("Words.txt") 

AnyOtherOfYourClassesWhateverThePackageIs.class.getResourceAsStream("/com/foo/Words.txt") 

classLoader.getResourceAsStream("com/foo/Words.txt")