关于在打包Jar文件时遇到的资源路径问题(一)

时间:2022-11-30 09:04:29

  当我们将程序写好,并进行打包成Jar文件时,通常都带有各种资源,这些资源可以是图像或者声音文件,也可以是别的如文本文件或二进制文件等,这些资源都和代码密切相关。例如在一个JPanel类上显示一些可能变化的信息,通常都是讲这些信息先写在文本文件上,而不是硬写入JPanel中,因为信息可能会变。而这文本文件就是这个程序的资源。

获得这些资源的位置有两种方式:

  1. 针对图像和影音的,使用包含这代码的类调用getResource(......)方法,然后利用getImage或者getAudioClip方法进行读取。例如TextPanel.class.getResource(......)或者this.getClass().getResource(.......)
  2. 针对其他文件类型的,使用包含该文件代码的类调用getResourceAsStream(......)方法,使用过程类似上一条示例。

不管是getResource(......)方法还是getResourceAsStream(......)方法,这里的“.......”是指资源位置的地方,这个是整个使用过程中最容易出错的地方。

那么这两种方法的资源路径该如何写呢?

 修改:以下所有内容为资源没有放入Jar包中时的情况,如果将资源同代码一起打包进Jar包中,请看 《关于在打包Jar文件时遇到的资源路径问题(二)》

正如我在 《关于在打包Jar文件时遇到的资源路径问题(二)》中最后总结的,这些方法都必须根据实际情况进行选择:

如果是资源需要经常修改,那么就可以使用本文所介绍的方法,将可执行Jar包和资源分离,这样易于改动,而不需要将Jar包解压修改后在复原;

如果是某些资源不需要修改,那么就可以使用《关于在打包Jar文件时遇到的资源路径问题(二)》中的方式,将资源和字节码文件一起打包进Jar包中,这样易于将应用程序移动,

当然,如果结合这两者方式,对固定资源和常修改资源进行分类处理,能获得更好的效果。

==============================正文开始====================================================

(1). 当在项目中有使用自定义包的情况下,一定要使用绝对资源位置(位置最前面要加“/”):

  1.1  当在Eclipse调试过程中,即还未打包成Jar文件之前的运行时:

  需要认识到getResource方法和getResourceAsStream的默认根目录都是当前Project项目的二进制bin文件夹中,也就是说我往“.......”写入的路径都是从XXX(Project)/bin文件夹开始的。

  例如:

  我的一个程序ImageViewer在包fjdingsd.com.cnblogs中,而这个包在E:\Java_Program\GUIproject\bin文件夹中,所以我写的路径应该为:/XXX(资源名)

  有如下代码:

 URL picUrl = this.getClass().getResource("/palette.gif");
Image image = new ImageIcon(picUrl).getImage();

这个资源文件的放置应该如下图所示:

关于在打包Jar文件时遇到的资源路径问题(一)(请忽略那个com文件夹)

  这里将palette.gif图片放到了GUIproject项目下的bin文件夹中,正如代码所示,/palette.gif地址就是以项目下的bin文件夹开始,当然我们也可以将该资源放到这个文件夹下的子目录中,例如创建一个pictures文件夹,将palette.gif放入,那么代码就该修改为:

 chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/pictures/palette.gif");

  对应的文件放置:

关于在打包Jar文件时遇到的资源路径问题(一)

这里请注意:

  填写资源位置时应该使用“/”作为分隔符,而不要理睬系统实际使用的哪种目录分隔符,在Windows系统中,资源加载器会自动将 “/” 装换成“\” 。

另外在在Eclipse调试运行过程中,必须以“/”作为最开头,这也称作绝对资源位置,如果不以“/”作为开头,那么程序运行就会出错:

关于在打包Jar文件时遇到的资源路径问题(一)

其实也很好理解,就是默认的地址XXX(Project)/bin文件夹的结尾没有“/”,所以我们要加入“/”,这样最终路径才能是XXX(Project)/bin文件夹 /pictures/palette.gif。

==========================================================

1.2  当程序打包成可执行Jar包时:

  这个时候资源就不是放XXX(Project)/bin文件夹下了,而是根据Jar包的位置来作为根目录:

  例如代码中写着:

URL picUrl = this.getClass().getResource("/palette.gif");
Image image = new ImageIcon(picUrl).getImage();

那么palette.gif就该与Jar包同一个目录下,而Jar包可以在任何目录中:

关于在打包Jar文件时遇到的资源路径问题(一)

这样点开程序就能运行了,如果资源路径前没有加“/”,则无论怎么点Jar包都不会有反应。

同理,如果代码是这么写着:

chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/pictures/palette.gif");

那么就可以在Jar包所在目录下建立子目录来放置资源文件,资源文件就该放入相应子目录中:

关于在打包Jar文件时遇到的资源路径问题(一)          关于在打包Jar文件时遇到的资源路径问题(一)

最后getResourceAsStream的资源路径也是一样的。

==============================第一种情况介绍结束分割线=================================

(2). 当该项目没有建立包时,也就是使用默认包(缺省值)时,不一定使用绝对资源位置:

关于在打包Jar文件时遇到的资源路径问题(一)(图:建立项目默认包情况)

2.1 当在Eclipse调试过程中,即还未打包成Jar文件之前的运行时:

  此时无论是getResource方法还是getResourceAsStream方法,资源位置可以是绝对资源位置,也可以是相对资源位置(最前面不加“/”):

chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("palette.gif");

亦或:

chooser.setAccessory(new PreImageViewer(chooser));
URL picUrl = this.getClass().getResource("/palette.gif");

都是可以的。

  注意:但是palette.gif依然必须放在从XXX(Project)/bin文件夹中,也就是类文件class所在的目录中。

2.2  当程序打包成可执行Jar包时:

  资源位置代码的编写同2.1中描述的一样,无论是使用绝对资源位置还是相对资源位置,都是可以的。

  而当打包成可执行Jar包时,资源在文件中的放置如1.2中的方法完全相同。

====================================================================================

关于在打包Jar文件时遇到的资源路径问题(一)