java加载jar包中的库资源

1、加载jar包中资源
加载文件方法有很多,不过如果文件打包在jar包内如何进行加载呢?

路径可以很轻易的获取,不过jar包是一个文件,而非一个文件夹,jar包中的资源并未解压到外部环境中,因而我们无法通过常用的加载文件的方法获知jar包中文件。通常通过如下接口来读取jar包中文件:

InputStream in = this.getClass().getResourceAsStream("/lib/libexample.so");

这里路径是jar包中路径。
getResourceAsStream函数体如下,返回了jar包内文件的输入流

public InputStream getResourceAsStream(String name) {
        name = resolveName(name);
        ClassLoader cl = getClassLoader0();
        if (cl==null) {
            // A system class.
            return ClassLoader.getSystemResourceAsStream(name);
        }
        return cl.getResourceAsStream(name);
    }

主要利用了ClassLoader类。

每个类都有自定义的ClassLoader对象,并通过这个ClassLoader对象对类进行加载。

当JVM需要某类时,它根据名称向ClassLoader要求这个类,然后由ClassLoader返回这个类的class对象。ClassLoader负责载入系统的所有Resources(Class,文件,来自网络的字节流等),通过ClassLoader从而将资源载入JVM。

2、加载库文件
常用的加载库文件(不论是JNI库文件还是非JNI库文件)的方法包括如下两种

  • System.load 参数为库文件的绝对路径,可以是任意路径。

例如:

System.load("C://Documents and Settings//TestJNI.dll");
  • System.loadLibrary 参数为库文件名,不包含库文件的扩展名。

例如:

System. loadLibrary ("TestJNI");

3、code
如果需要加载jar包中.so文件,需要上面两个接口配合。基本思想是通过getResourceAsStream()读取jar包中资源的文件流,并将之存入临时文件,再通过System.load加载。

public static void load(String path) throws IOException {
        if(!path.startsWith("/")){
            throw new IllegalArgumentException("Wrong path :" + path);
        }
        //如果存在本文件,直接加载,并返回
        File inputFile = new File(path);
        if(inputFile.exists() && inputFile.isFile()){
            System.load(path);
            return;
        }

        String fileName = path.substring(path.lastIndexOf('/')+1);
        if(fileName == null || fileName.isEmpty()){
            throw new IllegalArgumentException("The fileName should not be null");
        }

        String prefix = fileName.substring(0, fileName.lastIndexOf(".")-1);
        String suffix = fileName.substring(fileName.lastIndexOf("."));

        //创建临时文件,注意删除
        File tmp = File.createTempFile(prefix, suffix);
        tmp.deleteOnExit();
        System.out.println(tmp.getAbsolutePath());

        byte[] buff = new byte[1024];
        int len;
        OutputStream out = new FileOutputStream(tmp);
        //从jar中读取文件流
        InputStream in = MyFileLoad.class.getResourceAsStream(path);
        try{
            while((len = in.read(buff)) != -1){
                out.write(buff, 0, len);
            }
        }finally {
            in.close();
            out.close();
        }
        //加载库文件
        System.load(tmp.getAbsolutePath());

    }
  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值