从jar中拷贝资源文件

why?在代码中读取各种各样的资源文件对程序猿们来说是屡见不鲜的事情,对于集成环境下(eclipse、idea)这些代码也总是能运行得好好的,一点都不会让程序猿操心,因此很多人会就此打住。直到这些代码被打成jar包A,然后模块B依赖A时可能就会出现找不到资源文件等各种各样的问题。比如说,我们使用System.load来装载库文件的话,即便我们能得到存放资源文件的路径/D:/project/demo.
摘要由CSDN通过智能技术生成

why?

在代码中读取各种各样的资源文件对程序猿们来说是屡见不鲜的事情,对于集成环境下(eclipse、idea)这些代码也总是能运行得好好的,一点都不会让程序猿操心,因此很多人会就此打住。直到这些代码被打成jar包A,然后模块B依赖A时可能就会出现找不到资源文件等各种各样的问题。比如说,我们使用System.load来装载库文件的话,即便我们能得到存放资源文件的路径/D:/project/demo.jar!/resource/test.dll,但是这种路径并不能成功的加载。我们可能马上会想到以下的解决办法:
1、把配置文件拷贝一份到模块B里面来呗,简单粗暴。
2、把配置文件放在硬盘某一固定位置,代码里面直接写死路径(或者根据当前环境dev/beta/product读取对应的路径)呗,一劳永逸。
以上方案似乎能解决燃眉之急,然后程序又运行得好好的,一点问题都没有,瞥一眼电脑右下角,原来这么晚了,关机下班走人。。。

对于1方案,我们既然把它独立出来一个模块,肯定是有其原因的,比如这个A要被BCDEFG等模块依赖,难道要我们在BCDEFG等模块都放一份资源文件?如果资源文件经常变动,到时就要各个模块去更新文件,想想都觉得很可怕,有木有?
对于2方案,生产环境上的每台服务器都得丢一份文件上去,会不会有的服务器忘记呢?可能有人说我们用共享。不管怎样,当资源文件变了之后,项目发布之前,你依旧得去更新一下,很难说哪天真的忘记了…

综上,上面两种方案只能适合救急,绝非长久之计。要是程序运行时能自动把jar包里我们需要的资源文件拷贝到某一位置,这样代码就能正常的读取资源了。不管你有几个依赖模块A,不管你最终是war包,还是jar包,只管修改模块A的资源,发布项目的自动拷贝资源,这是就完全不需要额外的操作了。
java.net.URL和java.net.URLConnection类就可以帮我们拿到jar中的资源文件的输入流,然后我们把这个输入流写到指定位置就可以了。

how?

假设部署后模块A的路径在/usr/local/project/demo.jar

1、首先要确定的这个指定位置
getClass().getProtectionDomain().getCodeSource().getLocation()如果直接执行.class文件那么会得到当前class的绝对路径。如果封装在jar包里面执行jar包那么会得到当前jar包的绝对路径。

URL url = getClass().getProtectionDomain().getCodeSource().getLocation();
recourseFolder = java.net.URLDecoder.decode(url.getPath(), "utf-8");

此时我们得到的recourseFolder为/usr/local/project/demo.jar

if (recourseFolder.endsWith(".jar")) {
    recourseFolder = recourseFolder.substring(0, recourseFolder.lastIndexOf('/') + 1);
}
  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值