Java读取jar包中的resource资源文件

2023-05-16

目录

1、需求

2、问题

3、IDEA读取resource资源

3.1、方法1

3.2、方法2

4、打成jar包后读取resource资源

4.1、读取jar包中的资源文件

4.2、遍历jar包资源目录

4.2.1、环境判断

4.2.2、复制本地项目的资源文件

4.2.3、复制jar包里的资源文件


1、需求

        在Java项目中,需要读取resource资源目录下的文件,以及遍历指定资源目录下的所有文件,并且在读取文件时保留文件相对路径。

2、问题

        在IDEA中运行时,可以获取并遍历指定资源,但是将Java项目打成jar包运行后,就无法获取resource资源目录下的文件。

3、IDEA读取resource资源

        编译后,资源文件放在target目录下,每一个资源文件实实在在存在于磁盘中。

3.1、方法1

        直接通过绝对路径读取,如果file是目录,也可以通过listFiles递归遍历目录下文件:

String absolutePath = "资源文件绝对路径";
File file = new File(absolutePath);
if (file.isDirectory()) {
    File[] children = file.listFiles();
}

3.2、方法2

        通过相对路径读取:

String path = "template";    //相对resource路径
File file = ResourceUtils.getFile(ResourceUtils.CLASSPATH_URL_PREFIX + path);
if (file.isDirectory()) {
    File[] children = file.listFiles();
}

4、打成jar包后读取resource资源

        以上两种方法无法读取jar包中的资源文件。

        打成jar包后,jar包是一个单独的文件而不是文件夹,所以通过文件路径是无法定位到资源文件的。此时,可通过类加载器读取jar包中的资源文件。

4.1、读取jar包中的资源文件

        这种方式只能读取jar包中单个文件,因为读取出来的是InputStream流,无法保留文件相对于resource的路径,所以无法对jar包中资源进行遍历。

String path = "/resource相对路径";
InputStream is = this.class.getResourceAsStream(path);
byte[] buff = new byte[1024];
String filePath = "保存文件路径";
String fileName = "保存文件名";
File file = new File(filePath + fileName);
FileUtils.copyInputStreamToFile(is, file);

4.2、遍历jar包资源目录

以复制resource资源目录为例,分别对本地和jar包中的资源进行复制。

如下所示:

我要复制resource资源目录下的template文件夹下的所有内容;

然后保存到C:/Users/ASUS/Desktop/savePath文件夹下。

4.2.1、环境判断

public static void main(String[] args) throws URISyntaxException {
    // Test为当前类名
	URI uri = Test.class.getProtectionDomain().getCodeSource().getLocation().toURI();
	// tempPath: 文件保存路径
	String tempPath = "C:/Users/ASUS/Desktop/savePath";
	String sourceDir = "template";  //资源文件夹
	if (uri.toString().startsWith("file")) {
        // IDEA运行时,进行资源复制
		copyLocalResourcesFileToTemp(sourceDir + "/", "*", tempPath + "/" + sourceDir);
	} else {
		// 获取jar包所在路径
		String jarPath = uri.toString();
		uri = URI.create(jarPath.substring(jarPath.indexOf("file:"),jarPath.indexOf(".jar") + 4));
        // 打成jar包后,进行资源复制
		Test.copyJarResourcesFileToTemp(uri, tempPath, "BOOT-INF/classes/" + sourceDir);
	}
}

4.2.2、复制本地项目的资源文件

/**
     * 复制本地资源文件到指定目录
     * @param fileRoot      需要复制的资源目录文件夹
     * @param regExpStr     资源文件匹配正则,*表示匹配所有
     * @param tempParent    保存地址
     */
    public static void copyLocalResourcesFileToTemp(String fileRoot, String regExpStr, String tempParent) {
        try {
            ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[] resources = resolver.getResources(fileRoot + regExpStr);
            for (Resource resource : resources) {
                File newFile = new File(tempParent, resource.getFilename());
                if (newFile.exists()) {
                    newFile.delete();
                }
                InputStream stream = null;
                try {
                    stream = resource.getInputStream();
                } catch (Exception e) {
                    // 如果resource为文件夹时,会报异常,这里直接忽略这个异常
                }
                if (stream == null) {
                    newFile.mkdirs();
                    copyLocalResourcesFileToTemp(fileRoot + resource.getFilename()  + "/", regExpStr, tempParent + "/" + resource.getFilename());
                } else {
                    if (!newFile.getParentFile().exists()) {
                        newFile.getParentFile().mkdirs();
                    }
                    org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, newFile);
                }
            }
        } catch (Exception e) {
            log.error("failed to copy local source template", e);
        }
    }

4.2.3、复制jar包里的资源文件

/**
     * 复制jar包中的资源文件到指定目录
     * @param path          jar包所在路径
     * @param tempPath      保存目录
     * @param filePrefix    需要进行复制的资源文件目录:以BOOT-INF/classes/开头
     */
    public static void copyJarResourcesFileToTemp(URI path, String tempPath, String filePrefix) {
        try {
            List<Map.Entry<ZipEntry, InputStream>> collect =
                    readJarFile(new JarFile(path.getPath()), filePrefix).collect(Collectors.toList());
            for (Map.Entry<ZipEntry, InputStream> entry : collect) {
                // 文件相对路径
                String key = entry.getKey().getName();
                // 文件流
                InputStream stream = entry.getValue();
                File newFile = new File(tempPath + key.replaceAll("BOOT-INF/classes", ""));
                if (!newFile.getParentFile().exists()) {
                    newFile.getParentFile().mkdirs();
                }
                org.apache.commons.io.FileUtils.copyInputStreamToFile(stream, newFile);
            }
        } catch (IOException e) {
            log.error("failed to copy jar source template", e);
        }
    }
@SneakyThrows
    public static Stream<Map.Entry<ZipEntry, InputStream>> readJarFile(JarFile jarFile, String prefix) {
        Stream<Map.Entry<ZipEntry, InputStream>> readingStream =
                jarFile.stream().filter(entry -> !entry.isDirectory() && entry.getName().startsWith(prefix))
                        .map(entry -> {
                            try {
                                return new AbstractMap.SimpleEntry<>(entry, jarFile.getInputStream(entry));
                            } catch (IOException e) {
                                return new AbstractMap.SimpleEntry<>(entry, null);
                            }
                        });
        return readingStream.onClose(() -> {
            try {
                jarFile.close();
            } catch (IOException e) {
                log.error("failed to close jarFile", e);
            }
        });
    }

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java读取jar包中的resource资源文件 的相关文章

随机推荐

  • 技巧 | 如何画出漂亮的深度学习模型图

    点击上方 AI遇见机器学习 xff0c 选择 星标 公众号 重磅干货 xff0c 第一时间送达 仅作分享 xff0c 不代表本公众号立场 xff0c 侵权联系删除 转载于 xff1a 专知 现在搞AI研究写论文 xff0c 其中论文里的框架
  • 在树莓派上安装debian系统实现wifi渗透

    在树莓派上安装debian系统实现wifi渗透 步骤一 xff1a 下载官方安装包和镜像烧录工具 安装镜像 xff1a https www raspberrypi org downloads raspbian 安装工具 xff1a http
  • linux服务器内网磁盘映射、文件夹共享存储

    1 当前局域网两台服务器 xff1a 服务器1 xff1a 192 168 1 2 服务器2 xff1a 192 168 1 3 如果是虚拟机或者云主机需要在安全组增加允许tcp 任何端口 访问 192 168 1 0 24 想把服务器2
  • 想获得50亿专项激励?关于穿山甲新星助推计划你必须了解的几件事

    最近经常有开发者向我讲述他们在产品变现时候面临的一些痛点 xff1a 我是开发者 xff0c 想做流量变现 xff0c 不知道如何接广告 随便找到了一个平台没想到点击率和单价这么低 接入某某广告平台的流程异常复杂 xff0c 审核资料要求极
  • greenplum--gpfdist

    文章目录 命令格式实例 gpfdist是Greenplum中并行文件分发程序 使用它创建可读外部表时 xff0c 来自gp的数据段都是并行的 命令格式 gpfdist span class token punctuation span d
  • 一张图告诉你可刷armbian的电视盒子晶晨系列

  • VSCode将某个字符替换为换行符,并换行显示

  • WSL1 和 WSL2 从C盘 导入到 D盘

    win10 wsl 从C盘移除 WSL 1导出导入使用 windows Terminal 打开 powershell 标签wsl help 查看支持的子选项命令将wsl 系统打包注销已经导出的wsl导入修改windows terminal
  • 修改mysql字符集为utf8mb4

    设置mysql字符集为utf8mb4 要求MySQL版本 gt 61 5 5 3 查看字符集 查看MYSQL数据库服务器和数据库字符集 方法一 xff1a show variables like 39 character 39 方法二 xf
  • spyder中安装第三方库的包

    最近遇到一个问题 xff1a 在CMD命令窗口安装的python包 xff0c 在anaconda中spyder编辑器中找不到已安装的python包 xff0c 经过网上的资料查看 xff0c 原来是因为 xff0c cmd中python包
  • ubuntu16.04解决wifi被禁用的问题

    点击启用wifi xff0c 可wifi显示被禁用的问题解决 xff1a 1 终端输入命令 xff0c 查看当前wifi开关状态 xff0c 联想电脑会有出现ideapad laptop 影响无线wifi开关的 xff1a rfkill l
  • win10中WSL与Intel Haxm系列模拟器产生冲突

    windows 中的 wsl 基于微软自家的 Hyper V ms WHPX 系虚拟化加速 有些第三方的安卓模拟器 xff0c 基于 Intel 家的 Haxm Intel Haxm 系虚拟化加速 但是 xff0c 一个运行中的系统 xff
  • Windows10安装ubuntu(WSL2,可直接调用Win10程序) —2022年笔记

    算是wsl2的使用总结 一 启动win10虚拟机模块 1 打开控制面板 xff08 或开始 gt 运行 control xff09 2 点击最左边的 启用或关闭windows功能 xff0c 会弹出模块勾选界面 3 勾上 Hyper V 适
  • MySQL分组后取每一组第N条数据

    1 知识点 group concat 函数 聚合函数 1 功能 xff1a 将group by产生的同一个分组中的值连接起来 xff0c 返回一个字符串结果 2 语法 xff1a group concat distinct 要连接的字段 o
  • TDengine的安装使用(超详细)

    TDengine的安装使用 目录 FastBee物联网使用TDengine作为时序数据库 xff0c 蜂信物联官网 xff0c 开源项目演示 xff1a FastBee文档 xff1a 立即开始 TDengine 文档taos的配置参数客户
  • 双系统安装教程(win10 & ubuntu20.04)

    双系统安装教程 xff08 win10 amp ubuntu20 04 xff09 背景创建启动盘win10下磁盘划分开始安装吧我的分区设置启动项 背景 最近公司项目开发需要linux系统 xff08 yocto构建 xff09 xff0c
  • python3.x 快速入门

    Edit the gt 2018 6 15 11 26 53 1认识Python 人生苦短 我用python 优雅 明确 简单 是python设计哲学 python的设计目标之一 是让代码具备高度的可阅读性 python 被广泛用于web程
  • python字符串和列表的切片

    python字符串和列表的切片 前言1 切片字符串例子2 切片语法说明3 列表切片例子演练总结 前言 对于字符串和列表python提供了以 start end step 直观方式来截取字符串和列表一部分 xff0c 使用起来非常便利和直观
  • Debian安装

    欢迎访问爱招飞网站https www isoface cn获取更多物联网产品技术信息 Debian 是一个自由的操作系统 xff08 OS xff09 xff0c 提供您安装在计算机上使用 操作系统就是能让您的计算机工作的一系列基本程序和实
  • Java读取jar包中的resource资源文件

    目录 1 需求 2 问题 3 IDEA读取resource资源 3 1 方法1 3 2 方法2 4 打成jar包后读取resource资源 4 1 读取jar包中的资源文件 4 2 遍历jar包资源目录 4 2 1 环境判断 4 2 2 复