关于读取jar包中文件的问题

如何读取jar包中的资源文件?
读取jar包中的资源文件使用常规的方法是不行的,需要使用类加载器ClassLoader及其相关方法。

1.ClassLoader 是类加载器的抽象类。

她可以在运行时动态的获取加载类的运行信息。 可以这样说,当我们调用ResourceJar.jar中的Resource类时,JVM加载进Resource类,并记录下Resource运行时信息(包括Resource所在jar包的路径信息)。而ClassLoader类中的方法可以帮助我们动态的获取这些信息。

  • public URL getResource(String name)
    查找具有给定名称的资源。资源可以通过类代码访问并返回资源的URL对象。
  • public InputStream getResourceAsStream(String name);
    返回读取指定资源的输入流。这个方法很重要,可以直接获得jar包中文件的内容。

2.ClassLoader是abstract的,不可能实例化,更不可能通过ClassLoader调用上面两个方法。

所以我们真正写代码的时候,是通过Class类中的getResource()和getResourceAsStream()方法,这两个方法会委托ClassLoader中的getResource()和getResourceAsStream()方法 。

package edu.hxraid;
import java.io.*;
import java.net.URL;
public class Resource {
    public  void getResource() throws IOException{  
              //查找指定资源的URL,其中res.txt仍然开始的bin目录下 
        URL fileURL=this.getClass().getResource("/resource/res.txt"); 
        System.out.println(fileURL.getFile());
    }
    public static void main(String[] args) throws IOException {
        Resource res=new Resource();
        res.getResource();
    }
}

运行这段源代码结果:/E:/Code_Factory/WANWAN/bin/resource/res.txt (../ Code_Factory/WANWAN/.. 是java project所在的路径)。
我们将这段代码打包成ResourceJar.jar ,并将ResourceJar.jar放在其他路径下(比如 c:\ResourceJar.jar)。然后另外创建一个java project并导入ResourceJar.jar,写一段调用jar包中Resource类的测试代码:

import java.io.IOException;
import edu.hxraid.Resource;
public class TEST {
    public static void main(String[] args) throws IOException {
        Resource res=new Resource();
        res.getResource();
    }
}

这时的运行结果是:file:/C:/ResourceJar.jar!/resource/res.txt
当然不可以使用如下形式引用资源
File f=new File("C:/ResourceJar.jar!/resource/res.txt");
jar中的资源有其专门的格式

这也就是为什么源代码打包成jar文件后,调用时会报出FileNotFoundException的原因所在了。

3.使用Class类的getResourceAsStream()方法来获取jar包中的资源。

package edu.hxraid;
import java.io.*;
public class Resource {
    public void getResource() throws IOException{
        //返回读取指定资源的输入流
        InputStream is=this.getClass().getResourceAsStream("/resource/res.txt"); 
        BufferedReader br=new BufferedReader(new InputStreamReader(is));
        String s="";
        while((s=br.readLine())!=null)
            System.out.println(s);
    }
}

4.其他

读取jar文件中的文件,用类加载器,亦可以读取到文件。URL中有一个getFile()方法。
File f = new File(URL.getFile());
但这种方法URL的路径中不支持中文和空格(用%20代替了)。可以:
getClass().getResource("/a.txt").getPath().replaceAll("%20", " ")
getClass().getResource("a.txt").getPath().replaceAll("%20", " ")
第一种从根目录(当前类的最外层包的父目录)搜索资源;
第二种从当前类所在目录搜索资源。
类加载器加载的资源文件都要在classpath下。
还需注意的是路径在windows文件系统中时是不分大小写的,但一旦打入jar包就大小写敏感了。

你可能感兴趣的:(关于读取jar包中文件的问题)