我目前正在编写一个基于servlet的应用程序(客户端)。我试图在代码所在的同一包中获取一个文本文件。我遇到的所有方法都使用MyClass.class.getResourceAsStream("Words.txt")或classLoader.getResourceAsStream("Words.txt")获取了文本文件(例如:SO1,SO2)。但是我已经尝试过FileInputStream("./src/package/Words.txt")了,文本文件仍然可以成功加载。
MyClass.class.getResourceAsStream("Words.txt")
classLoader.getResourceAsStream("Words.txt")
FileInputStream("./src/package/Words.txt")
有什么区别?为何getResourceAsStream鼓励使用该方法?
getResourceAsStream
目前,您正在开发人员工作站上,并且可能正在通过IDE运行您的应用程序。Tomcat恰好是从IDE项目根目录启动的,因此使用
new FileInputStream("./src/package/Words.txt")
允许读取存储在项目src目录中的文件。
src
但这不是项目在生产中的运行方式。在生产中,将使用Shell脚本从完全不同的目录启动Tomcat服务器。生产服务器将根本没有源项目。它所拥有的只是Tomcat,以及构成该项目构建的工件的war文件。
因此,将根本没有src目录,并且文件Words.txt甚至不会在文件系统上的任何位置。它只会是war文件(实际上是zip文件)的入口,该文件WEB- INF/classes/package与.class编译器从Java源文件生成的文件一起位于下面。
Words.txt
WEB- INF/classes/package
.class
因此,为了能够读取该“文件”,您不能使用文件IO:“文件”在文件系统中不存在。您需要使用ClassLoader,它将在war文件中找到“文件”并从那里加载它。
当应用程序从爆炸的战争结构运行时,这在开发过程中也将很好:类加载器将在IDE所使用的目标目录下找到用于存储类文件和资源文件的类。
请注意,如果资源在软件包中,com.foo而MyClass在同一软件包中,则需要加载的资源是
com.foo
要么
AnyOtherOfYourClassesWhateverThePackageIs.class.getResourceAsStream("/com/foo/Words.txt")
classLoader.getResourceAsStream("com/foo/Words.txt")