对接海康sdk-linux下复制jar包中resource目录的文件夹

背景

在集成海康sdk时,需要将一些组件放到项目中作为静态资源,并且海康的sdk初始化也需要加载这些静态资源,在windows下,使用一些File路径的方式是可以正确加载的,但是在linux上就会加载失败。
首先我是将海康的sdk组件放到resource下的,并且按照windows和linux设置了两个文件夹,打成jar包后,在linux上会出现访问不了资源的情况。

项目结构

在这里插入图片描述

在这里插入图片描述

linux上加载失败原因

打成jar包后,jar包就相当于一个压缩包,此时无法获取resource目录下的文件路径。

解决方案

将lib/linux下整个文件全部复制到当前项目的目录下,就相当于放在了与jar包平级的目录下,例如jar包路径:/opt/a/xx.jar,那复制会组件库的位置就在/opt/a,这时应用只需要读取新的组件库位置,就能正确加载组件库了。

处理

核心处理:

  1. 使用ResourcePatternResolver类,可以获取resource下符合条件的所有资源名
  2. 获取的Resource对象,是没有方法可以判断到底是文件夹还是文件的,这里我通过实验发现一个可行办法。。。如果是文件夹,那么resource.getFilename()是一定为空的,因为文件夹其实并不算一个资源,
  3. 写文件时必须使用流,不能用File对象

结果

以下是处理resource目录下文件夹或文件复制的工具类

package com.lezhi.szxy.hkEducation.util;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.resource.ResourceUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.core.io.Resource;
import java.io.*;
import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * @author:hahaha
 * @creattime:2021-12-02 10:33
 */

@Slf4j
public class ResourceFileUtil {
   

    /**
     * 复制resource下指定文件夹内所有的文件至目标目录,包括子文件夹
     * @param sourcePath  classpath文件路径,例如 static/hk
     * @param newPath 目标目录
     */
    public static void copyFolderFromResource(String sourcePath, String newPath) throws IOException {
   
        log.info("源文件夹:{}, 目标文件夹:{}", sourcePath, newPath);
        if (!FileUtil.exist(newPath)) {
   
            FileUtil.mkdir(newPath);
        }
        // 注意:一定要使用/**,获取所有匹配的文件,包括子文件夹及其下的文件
        // /* 只能获取该目录下的一级目录下的文件,无法继续下转获取子文件夹的文件,并且/* 无法获取子文件夹,这里说的是文件夹哈,即连Resource对象都不会存在
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext();
        Resource[] resources = context.getResources(sourcePath + File.separator  + "**");
        // 在linux下运行时,resource必须是ClassPathResource类型,其打印的Description格式为 class path resource [lib/linux/HCNetSDKCom/],可通过日志查看是否加载正确,如果不正确,说明项目结构有问题,无法识别classpath
        // 在windows下运行时,resource有可能是FileSystemResource类型,其打印的Description格式为 file [xxxx]
        log.info("sourcePath 下的资源列表:{}", Arrays.stream(resources).map(Resource::getDescription).collect(Collectors.toList()));
        Arrays.stream(resources).forEach(resource -> {
   
            try {
   
                // 获取目标文件夹的 下级及子级目录
                String filename = getRealPathFromDesc(resource, sourcePath);
                if (StrUtil.isBlank(filename) || File.separator.equals(filename)) {
   
                    return;
                }
                String destFilePath = newPath + filename;
                // getFilename为空说明是文件夹,ClassPathResource下的文件夹就是空的资源名
                // 如果是文件系统,则直接判断文件是否是文件夹
                if (StrUtil.isBlank(resource.getFilename()) ||
                   (resource instanceof FileSystemResource && resource.getFile().isDirectory())
                ) {
   
                    if (!FileUtil.exist(destFilePath)) {
   
                        new File(destFilePath).mkdirs();
                    }
                    return;
                }

                // 否则是文件资源,则直接写文件
                FileUtil.writeFromStream(resource.getInputStream(), destFilePath);
            } catch (Exception e) {
   
                log.
  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

巴中第一皇子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值