Spring Boot 2.X 加载 so 库

新建临时目录

首先通过 System.getProperty 获取系统环境变量

System.getProperty("java.io.tmpdir")

  • 在 windows 上,C:\Users\用户名\AppData\Local\Temp\
  • 在 Linux 上,/tmp/

需要在该目录下,新建一个项目文件夹,用来存放当前项目的文件。

下面以 bsdiff 服务器,加载 so 为例(与 File.separator 是与系统相关的环境分隔符 )

public static final String TMP_DIR = System.getProperty("java.io.tmpdir") + "BsDiff" + File.separator;

放置资源文件

首先在 src\main\resources 目录下,新建一个 lib 目录,然后在该目录下,贴入 so 库。
在这里插入图片描述

读取资源文件

  1. Class.getResourceAsStream(String path)
  • path不以“/”开头时,默认是从当前类所在的包下面获取资源
  • path以“/”开头时,则是从项目的classPath根下获取资源
  1. ClassLoader.getResourceAsStream(String path)
    默认是从classpath根下获取,path不能以“/”开头,path是指类加载器的加载范围,在资源加载的过程中,使用逐级向上的委托的形式加载的,“/”表示Boot ClassLoader中的加载范围,因为这个类加载器是C++实现的,所以加载范围为null。

  2. ServletContext.getResourceAsStream(String path)
    默认从WebAPP根目录下取资源,Tomcat下path是否以“/”开头无所谓,当然这和具体的容器实现有关。

创建一个 LibLoader 类。

/**
 * 将resources目录下的文件,写入到File中
 */
private static boolean saveResource(String resourcePath, File dstFile) {
	InputStream in = null;
	FileOutputStream fos = null;
	try {
		in = LibLoader.class.getResourceAsStream(resourcePath);
		System.out.println("in = " + in);
		if(in != null) {
			fos = new FileOutputStream(dstFile);
			int BUFF_SIZE = 1024, len;
			byte[] buffer = new byte[BUFF_SIZE];
			while((len = in.read(buffer)) != -1) {
				fos.write(buffer, 0, len);
			}
			return true;
		}
	} catch(Exception e) {
		e.printStackTrace();
	} finally {
		if(fos != null) {
			try {
				fos.flush();
				fos.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if(in != null) {
			try {
				in.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	return false;
}

调用函数

注意:由于资源文件在 resources 目录下,所以 getResourceAsStream 的参数要以 “/” 打头。

下面这段代码,先判断缓存目录下是否有该so文件,如果有,则使用 System.load 加载该库;否则

public static void loadLib(String libName) {
	String folderName = System.getProperty("java.io.tmpdir") + "BSDiff" + File.separator + "lib" + File.separator;
	File folder = new File(folderName);
	folder.mkdirs();
	File libFile = new File(folder, libName);
	String path = libFile.getAbsolutePath();
	//如果文件不存在,或者文件长度为0,则从资源路径中复制文件到临时文件夹
	if(libFile.exists() && libFile.length() > 0) {
		System.load(path);
	} else {
		String resourcePath = "/lib/" + libName;
		System.out.println(resourcePath);
		boolean result = saveResource(resourcePath, libFile);
		if(result) {
			System.load(path);
		} else {
			System.out.println("save resource to tmp dir fail!");
		}
	}	
}	

加载 so 库

最后声明含有本地方法的类,然后实例化并调用即可。
注意:如果只是声明,却没有被实例化,static 方法块内的代码是不会被执行的。

public class DiffPatchUtil {

    static {
        //System.loadLibrary("diff-patch");
    	LibLoader.loadLib("diff-patch.so");
    }

    /**
     * 比较路径为oldPath的文件和newPath的文件之间差异,并生成patch包,存储于patchPath
     *
     * @param oldPath   示例:/sdcard/old.apk
     * @param newPath   示例:/sdcard/new.apk
     * @param patchPath 示例:/sdcard/diff.patch
     */
    public static native int diff(String oldPath, String newPath, String patchPath);

    /**
     * 使用路径为oldPath的文件与路径为pathPath的补丁包,合成新的文件,并存储于newPath
     *
     * @param oldPath   示例:/sdcard/old.apk
     * @param newPath   示例:/sdcard/new.apk
     * @param patchPath 示例:/sdcard/patch.patch
     */
    public static native int patch(String oldPath, String newPath, String patchPath);
}
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值