WEB开发网
开发学院软件开发Java 读取jar包内部配置文件信息的解析 阅读

读取jar包内部配置文件信息的解析

 2012-05-20 08:02:36 来源:WEB开发网   
核心提示: 读取jar文件内部的配置信息是在进行开发基于java程序组件时必然会遇到的问题,这里所遇到的问题是在开发测试和部署(也就是将程序打成jar包之后供其他组件调用)时往往会不一致,读取jar包内部配置文件信息的解析,也就是开发的时候我们的代码可以访问到配置文件信息,但是一旦打成jar包之后往往会遇到“File

 读取jar文件内部的配置信息是在进行开发基于java程序组件时必然会遇到的问题,这里所遇到的问题是在开发测试和部署(也就是将程序打成jar包之后供其他组件调用)时往往会不一致。也就是开发的时候我们的代码可以访问到配置文件信息,但是一旦打成jar包之后往往会遇到“FileNotFoundException”,也就是无法找到配置文件。下面看一个示例。

项目结构图 

这是一个测试项目,项目的结构如图所示,现在需要在Main.java类中读取conf.properties文件中的信息。

不一致行为
如果我们在代码中使用下面的语句

...
String confPath = "src/conf/conf.properties";
FileInputStream fis = new FileInputStream(new File(confPath));
config.load(fis);
...
那么我们打成jar包之前运行程序是可以读取到所要信息,但是打成jar包之后必然会遇到“FileNotFoundException”。而如果使用下面的代码

...
String confPath = "conf/conf.properties";
FileInputStream fis = new FileInputStream(new File(confPath));
config.load(fis);
...
那么无论是打包之前还是之后都会遇到“FileNotFoundException”的异常!
正确的做法
...
String confPath = "conf/conf.properties";
config.load(this.getClass().getClassLoader().getResourceAsStream(confPath));
...
这时,无论是在打jar包之前还是之后都可以正确读取conf.properties文件中的信息!
原因分析
上面两种截然不同的结果产生的原因是我们使用的FileInputStream和getResourceAsStream()方法的差异所造成的!所以原因也必然在于FileInputStream和getResourceAsStream()的不同。
根据JDK中的表述,FileInputStream是基于当前JVM所在的OS,在文件系统指定的路径中进行查找要求的资源。而ClassLoader类的getResourceAsStream()方面的描述如下:

public InputStream getResourceAsStream(String name)
返回读取指定资源的输入流。
getResource(String) 的文档中描述了搜索顺序。
参数:
name - 资源名称
返回:
用于读取资源的输入流,如果无法找到资源,则返回 null
从以下版本开始:
1.1
public URL getResource(String name)
查找具有给定名称的资源。资源是可以通过类代码以与代码基无关的方式访问的一些数据(图像、声音、文本等)。
资源名称是以 '/' 分隔的标识资源的路径名称。
此方法首先搜索资源的父类加载器;如果父类加载器为 null,则搜索的路径就是虚拟机的内置类加载器的路径。如果搜索失败,则此方法将调用 findResource(String) 来查找资源。

参数:
name - 资源名称
返回:
读取资源的 URL 对象;如果找不到该资源,或者调用者没有足够的权限获取该资源,则返回 null。
从以下版本开始:
1.1

从这段文字表述中我们不难发现,getResourceAsStream()在查找资源时跟JVM所用的OS毫无关系,甚至跟资源所在文件系统的路径也是无关的,它是基于类路径进行查找的!也就是说,当jar包或*.class文件加载之后,JVM会根据jar包或*.class文件所在的classpath属性去查找指定的资源,而这个classpath是在jar包的MANIFEST.MF文件中指定的,如下所示:
Manifest-Version: 1.0
Class-Path: .
Main-Class: com.webex.app.Main
这里的“.”代表当前路径,是一个相对路径,但是它相对的是一个“虚拟路径”,也就是jar或*.class文件加载到JVM后的“路径”!

Tags:读取 jar 内部

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接