获取jar包内部的资源文件
来源:互联网 发布:淘宝一元秒杀怎么玩 编辑:程序博客网 时间:2024/04/19 22:47
通常获取一个资源文件很简单,问题是对于jar包内的资源文件,可能会发生意外。假如这里有一个文件操作的类:
public class FileLoader {public boolean exists(){URL resource = FileLoader.class.getResource("/library/a.txt");if(resource==null){return false;}File f = new File(resource.getFile());return f.exists();}public static void main(String[] args) throws IOException {FileLoader f = new FileLoader();System.out.println(f.exists());}}
运行main方法它会读取当前根路径下(src/bin)的资源文件,假如存在目录library和子文件a.txt,这里会打印出true;
现在把这段代码和资源文件打成myfile.jar并运行在一个myeclipse工程中,我们期望也是打印true。然而控制台打印false;将其引入到war工程在tomcat中运行,依然打印false。
也就是说,资源文件的使用类无法找到自己,jar包正常的功能将无法提供。这是一个常见的关于jar路径的问题。
为了试验,在上面的FileLoader类中增加一个方法
public void printPath(){System.out.println("/目录: "+ FileLoader.class.getResource("/").getPath());System.out.println("\"\"目录: "+ FileLoader.class.getResource("").getPath());System.out.println("/library目录: "+ FileLoader.class.getResource("/library").getPath());}
运行后打印结果为:
/目录: /D:/Workspaces/ruleengine/file/target/classes/
""目录: /D:/Workspaces/ruleengine/file/target/classes/com/file/
/library目录: /D:/Workspaces/ruleengine/file/target/classes/library
重新打包后引入到一个当前myeclipse工程中,一定要以jar包的形式引入,不能通过myeclipse直接关联myfile工程。调用printPath后打印结果为:
/目录: /D:/Workspaces/ruleengine/schoolaround/target/test-classes/
""目录: file:/D:/Workspaces/ruleengine/schoolaround/lib/myfile.jar!/com/file/
/library目录: file:/D:/Workspaces/ruleengine/schoolaround/lib/myfile.jar!/library
显而易见,获取jar包中的文件路径的格式已经变为*.jar!*(除了第一个),这种格式的路径,不能通过new File的方式找到文件。目前本人也没有找到其它处理方式,欢迎评论指点。在这种情况下,如果想让jar读取到自己的资源文件,可以通过类加载器的getResourceAsStream方法来解决。
修改FileLoader类的exists方法如下:
public boolean exists() throws IOException{InputStream resource = FileLoader.class.getResourceAsStream("/library/a.txt");if(resource==null){return false;}return true;}这时无论是在哪里引入myfile.jar,执行exists方法时都会打印true。也就是说,资源文件一定能够被读取到。
似乎这个问题已经解决,其实不然。这只满足一种需求,那就是资源文件与它的使用类在同一个jar包中时。有时,我们需要让子工程读取放置在war工程根目录下的配置文件。假如需要将这里的资源文件(library/a.txt)放置在当前主工程中,而不是在myfile中,如何让myflie.jar正常工作呢?
是时候请出FileLoader.class.getResource("/")这句代码了。傲娇的她永远只返回当前工程的根路径,可以参见上诉不同位置调用printPath方法的打印结果。如果当前是运行在tomcat中的web工程,那么打印的路径为%tomcat%/webapps/工程名/WEB-INF/classes/目录(此目录对应于war工程的src目录);
不同的是,FileLoader.class.getResource("")或者FileLoader.class.getResource("/library")总是相对于调用类的所在位置而言的。此例中就是相对于FileLoader类所在位置而言的。
利用FileLoader.class.getResource("/")的傲娇特性,就可以解决第二种需求。
例如修改exists方法:
public boolean exists() throws IOException{String root = FileLoader.class.getResource("/").getPath();File f = new File(root+"library/a.txt");return f.exists();}
这样,把资源文件(library/a.txt)放置在当前工程的src目录下,引入myfile.jar依然可以正常工作。
总结
这里记录了由于读取jar文件内部资源问题而引起的两个需求,一个可以通过类加载器的getResourceAsStream绕开,另一个可以利用类加载器的getResource("/")方法永远返回当前工程根目录的特性解决。
另外有待日后补充的两点:1,对于在当前工程读取jar包中资源文件的需求,参考Spring父工程引入子工程context.xml的过程;2,对于getResource和getResourceAsStream的底层区别需要深入探索。
- 获取jar包内部的资源文件
- java中jar包内的类访问jar包内部的资源文件的路径问题
- java中jar包内的类访问jar包内部的资源文件的路径问题
- 从Jar包获取资源的方法
- 从Jar包获取资源的方法
- 读取jar包里的资源文件
- java从jar包中获取资源文件
- rcp 生成jar包后如何获取资源文件
- Java或者JAR包获取读取资源文件的路径的问题总结
- Java或者JAR包获取读取资源文件的路径的问题总结
- 打jar包获取assets中的资源 解决selector XML文件不能解析的问题
- Jar包读取内部和外部的文件
- Jar包读取内部和外部的文件
- getResources()方法读取jar包内部的文件
- Jar包读取内部和外部的文件
- 通过字段名称动态获取资源的id(将Android工程做成jar包和资源文件)
- 获取资源文件与从jar包中读取资源文件
- 从JAR包中获取资源的方法
- acticity嵌套fragmentA和fragmentB情景下生命周期介绍
- 问题
- JavaEE项目在WEB-INF目录下的jsp页面如何访问WebRoot中的CSS和JS文
- LintCode_最后一个单词的长度
- 序列标注模型
- 获取jar包内部的资源文件
- Failed to create keys in the OLR, rc = 127, Message:
- VM虚拟机中Linux扩展磁盘空间的方法
- php客户端neoclient遍历neo4j中的节点和关系及其属性等
- 中央经济工作会仅剩一月 经济冲刺年末考
- Android编译过程详解(一)
- sp_who
- redis-3.0集群安装
- 【B/S学习总结】我的第100篇CSDN博客