java: 关于从jar中读取资源遇到的问题getClass().getResource(...)

在Java的程序发布中,很多人会选择采用二进制的jar的格式进行发布,怎么样读取Jar里面的资源呢?
主要是采用ClassLoader的下面几个方法来实现:
public URL getResource(String name);
public InputStream getResourceAsStream(String name)

public static InputStream getSystemResourceAsStream(String name)
public static URL getSystemResource(String name)

我一般都是使用:

getClass().getResource(...);

比如,设置JFrame的图标:

this.setIconImage(new ImageIcon(getClass().getResource(...)).getImage());

但是我今天遇到的问题是,在程序中需要播放一个存放在jar中的notify.wav声音文件,我的代码:

System.out.println(getClass().getResource("/sound/notify.wav").getPath());
System.out.println(getClass().getResource("/sound/notify.wav").getFile());
System.out.println(getClass().getResource("/sound/notify.wav").toExternalForm());
System.out.println(getClass().getResource("/sound/notify.wav").toString());

/*

//输出的路径

/D:/soft/test/bin/sound/notify.wav
/D:/soft/test/bin/sound/notify.wav
file:/D:/soft/test/bin/sound/notify.wav
file:/D:/soft/test/bin/sound/notify.wav

*/

FileInputStream audioFIS = new   FileInputStream(getClass().getResource("/sound/notify.wav").getFile());

AudioPlayer.player.start(audioFIS); //播放声音

在eclipse中测试的时候,能正常播放声音,但打包成jar文件后,就提示找不到声音文件了。

为什么在最上面的设置窗口的图标时,可以,但在这里播放jar中的声音文件时就出错了呢?

最后通过在网上搜索,找到这篇介绍(http://www.iteye.com/topic/483115)才明白:

摘抄一部分内容:...........................

这主要是因为jar包是一个单独的文件而非文件夹,绝对不可能通过"file:/e:/.../ResourceJar.jar/resource /res.txt"这种形式的文件URL来定位res.txt。所以即使是相对路径,也无法定位到jar文件内的txt文件(读者也许对这段原因解释有些费解,在下面我们会用一段代码运行的结果来进一步阐述)。

因为".../ResourceJar.jar!/resource/...."并不是文件资源定位符的格式 (jar中资源有其专门的URL形式: jar:<url>!/{entry} )。所以,如果jar包中的类源代码用File f=new File(相对路径);的形式,是不可能定位到文件资源的。这也是为什么源代码1打包成jar文件后,调用jar包时会报出FileNotFoundException的症结所在了。

//解决办法也很简单,直接使用:getClass().getResourceAsStream()

InputStream audioIS = getClass().getResourceAsStream("/sound/notify.wav");;
AudioPlayer.player.start(audioIS);

2012-01-29

时间: 2024-12-16 11:16:56

java: 关于从jar中读取资源遇到的问题getClass().getResource(...)的相关文章

java 从jar包中读取资源文件

在代码中读取一些资源文件(比如图片,音乐,文本等等),在集成环境(Eclipse)中运行的时候没有问题.但当打包成一个可执行的jar包(将资源文件一并打包)以后,这些资源文件找不到,如下代码:Java代码 [java] view plaincopy //源代码1: package edu.hxraid; import java.io.*; public class Resource { public  void getResource() throws IOException{ File fil

(转)java 从jar包中读取资源文件

(转)java 从jar包中读取资源文件 博客分类: java 源自:http://blog.csdn.net/b_h_l/article/details/7767829 在代码中读取一些资源文件(比如图片,音乐,文本等等),在集成环境(Eclipse)中运行的时候没有问题.但当打包成一个可执行的jar包(将资源文件一并打包)以后,这些资源文件找不到,如下代码:Java代码 [java] view plaincopy //源代码1: package edu.hxraid; import java

[Java基础] 深入jar包:从jar包中读取资源文件

转载: http://hxraid.iteye.com/blog/483115?page=3#comments 我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看下面的代码: //源代码1: package edu.hxraid; import java.io.*; public class Resource { public void getRe

【解惑】深入jar包:从jar包中读取资源文件

我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看下面的代码: //源代码1: package edu.hxraid; import java.io.*; public class Resource { public void getResource() throws IOException{ File file=new File("bin/res

JAR包中读取资源文件

我们常常在代码中读取一些资源文件(比如图片,音乐,文本等等).在单独运行的时候这些简单的处理当然不会有问题.但是,如果我们把代码打成一个jar包以后,即使将资源文件一并打包,这些东西也找不出来了.看看下面的代码: 1 //源代码1: 2 3 import java.io.*; 4 public class Resource { 5 public void getResource() throws IOException{ 6 File file=new File("bin/resource/re

从jar包中读取资源

package myspider; import java.io.UnsupportedEncodingException; /** * * @author mark */ public class Test { public static void main(String[] args) throws UnsupportedEncodingException{ Test t=new Test(); //文件名前不加"/",则表示从当前类所在的包下查找该资源.如下则表示的是从包mysp

Java/JavaWeb中读取资源文件

1.一般工程中使用I/O类指定文件的绝对路径读取 FileInputStream fis = new FileInputStream("src/main/resources/zsm.properties"); ppt.load(fis); String memAddr1 = ppt.getProperty("memAddr1"); 2.Web工程中可以使用ServletContext或ClassLoader来读取 2.1.通过ServletContext来读取资源文

java如何在文件中读取一个字符串并创建以这个字符为名字的类的对象

<span style="font-family: Arial, Helvetica, sans-serif; background-color: rgb(255, 255, 255);">我们一般用properties或者XML文件作为资源存储的文件,现在主要介绍一下对properties的操作</span> 1.我们在src文件下新建一个名称为config的包 2.在config下新建一个file,把它命名为demo.properties 3. 把下面的几段

Java从内存流中读取byte数组

Java中通过servlet接收二进制数据,然后将二进制数据流读取为byte数组.开始使用:byte[] bs = new byte[request.getContentLength()];request.getInputStream().read(bs);return bs;数据量小的时候没有问题,数据量大了就读取不完整了,后来按如下修改即可. /** * 获取客户提交上来的数据 * @param request * @return */ private byte[] getData(Http