当前位置: 首页 > news >正文

通过java向jar写入新文件

文章目录

  • 原始需求
  • 分析
  • 实施步骤
      • 引入依赖
      • 核心编码
      • 运行效果

原始需求

有网友提问: 我想在程序中动态地向同一个jar包中添加文件,比如,我的可执行jar包是test.jar,我要在它运行时生成一些xml文件并将这些文件添加到test.jar中,请问如何实现?

分析

test.jar在运行过程中是无法改变自身内容的,但是可以创建内容与test.jar一致的test2.jar
问题就转换成了:

  1. 如何复制已有的test.jar重命名为test2.jar
  2. 如何继续向test2.jar添加新的文件

实施步骤

引入依赖

        <dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.5</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-compress</artifactId><version>1.23.0</version></dependency>

核心编码

借助 commons-compress 来操作Jar

    public void test()throws IOException{String src = getClass().getResource("/apache-jstl.jar").getPath();String add1 = getClass().getResource("/servlet-api.jar").getPath();String add2 = getClass().getResource("/log4j2.xml").getPath();String newJar = src.replace(".jar", DateFormatUtils.format(System.currentTimeMillis(), "_HHmmssSSS") + ".jar");log.info("源文件: {}", src);log.info("++新增: {}", add1);log.info("++新增: {}", add2);log.info("新文件: {}", newJar);try (ArchiveOutputStream outputStream = new JarArchiveOutputStream(new FileOutputStream(newJar));JarArchiveInputStream jarInput = new JarArchiveInputStream(new FileInputStream(src))){JarArchiveEntry jarEntry;while ((jarEntry = jarInput.getNextJarEntry()) != null){if (!jarEntry.isDirectory()){outputStream.putArchiveEntry(jarEntry);IOUtils.copy(jarInput, outputStream);}}outputStream.flush();// 追加addFilesFile[] addFiles = {new File(add1), new File(add2)};for (File addFile : addFiles){JarArchiveEntry addEntry = new JarArchiveEntry("add/" + addFile.getName());outputStream.putArchiveEntry(addEntry);try (InputStream entryInputStream = new FileInputStream(addFile)){IOUtils.copy(entryInputStream, outputStream);}}// 追加add/001.txtJarArchiveEntry entry = new JarArchiveEntry("add/001.txt");outputStream.putArchiveEntry(entry);outputStream.write("org.apache.commons.compress.archivers.jar.JarArchiveOutputStream;".getBytes(StandardCharsets.UTF_8));outputStream.closeArchiveEntry();outputStream.finish();}}

使用JDK API实现

public void test2(){try{String src = getClass().getResource("/apache-jstl.jar").getPath();String add1 = getClass().getResource("/servlet-api.jar").getPath();String add2 = getClass().getResource("/log4j2.xml").getPath();String newJar = src.replace(".jar", DateFormatUtils.format(System.currentTimeMillis(), "_HHmmssSSS") + ".jar");log.info("源文件: {}", src);log.info("++新增: {}", add1);log.info("++新增: {}", add2);log.info("新文件: {}", newJar);addFilesToJar(new File(src), newJar, new File(add1), new File(add2));}catch (IOException e){log.error(e.getMessage(), e);}}/*** JDK-API实现-将addFiles添加到srcJar并重命名为newJar* * @param srcJar* @param newJar* @param addFiles* @throws IOException*/private void addFilesToJar(File srcJar, String newJar, File... addFiles)throws IOException{try (JarOutputStream jarOutputStream = new JarOutputStream(new FileOutputStream(newJar)); JarFile jarFile = new JarFile(srcJar)){// 遍历jar文件数据写入新jarEnumeration<JarEntry> entrys = jarFile.entries();while (entrys.hasMoreElements()){JarEntry jarEntry = entrys.nextElement();if (!jarEntry.isDirectory()){jarOutputStream.putNextEntry(jarEntry);try (InputStream entryInputStream = jarFile.getInputStream(jarEntry)){IOUtils.copy(entryInputStream, jarOutputStream);}}}// 追加写入for (File addFile : addFiles){JarEntry jarEntry = new JarEntry("add/" + addFile.getName());jarOutputStream.putNextEntry(jarEntry);try (InputStream entryInputStream = new FileInputStream(addFile)){IOUtils.copy(entryInputStream, jarOutputStream);}}}}

运行效果

原始文件
在这里插入图片描述
运行后:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
大功告成!!!

有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

相关文章:

通过java向jar写入新文件

文章目录 原始需求分析实施步骤引入依赖核心编码运行效果 原始需求 有网友提问&#xff1a; 我想在程序中动态地向同一个jar包中添加文件&#xff0c;比如&#xff0c;我的可执行jar包是test.jar,我要在它运行时生成一些xml文件并将这些文件添加到test.jar中,请问如何实现&…...

uni-app_消息推送_华为厂商_unipush离线消息推送

文章目录 一、创建项目二、生成签名证书三、开通 unipush 推送服务四、客户端集成四、制作自定义调试基座五、开发者中心后台Web页面推送&#xff08;仅支持在线推送&#xff09;六、离线消息推送1、创建华为开发者账号2、开通推送服务3、创建项目4、添加应用5、添加SHA256证书…...

单元测试框架-Pytest(简单学习)

单元测试框架-Pytest Pytest是基于Python语言的单元测试框架&#xff0c;也是一个命令行的工具&#xff0c;比 unittest 测试框架更灵活。具有以下特点&#xff1a; 入门简单&#xff0c;易上手&#xff0c;官方文档丰富而且使用广泛&#xff0c;有大量的参数例子。 unittest…...

毛玻璃态卡片悬停效果

效果展示 页面结构组成 页面的组成部分主要是卡片。其中卡片的组成部分主要是包括了图片和详情。 卡片的动效是鼠标悬停在卡片上时&#xff0c;图片会移动到左侧&#xff0c;并且图片是毛玻璃效果。所以我们在布局的时候图片会采用绝对布局。而详情则是基础布局。 CSS3 知识…...

【面试经典150 | 数组】除自身以外数组的乘积

文章目录 写在前面Tag题目来源题目解读解题思路方法一&#xff1a;记录左右乘积空间优化 写在最后 写在前面 本专栏专注于分析与讲解【面试经典150】算法&#xff0c;两到三天更新一篇文章&#xff0c;欢迎催更…… 专栏内容以分析题目为主&#xff0c;并附带一些对于本题涉及到…...

uboot启动流程-涉及s_init汇编函数

一. uboot启动涉及函数 本文简单分析uboot启动流程中&#xff0c;涉及的汇编函数&#xff1a; lowlevel_init函数调用的函数&#xff1a;s_init 函数 save_boot_params_ret函数调用的函数&#xff1a; _main 函数 本文继上一篇文章的学习&#xff0c;地址如下&#xff1a;…...

单例模式详解及5种实现方式 (设计模式 一)

基本概念 在软件开发中&#xff0c;单例模式是一种常见的设计模式&#xff0c;用于确保一个类只有一个实例&#xff0c;并提供全局访问点。单例模式在需要确保只有一个对象实例存在的场景中非常有用&#xff0c;例如数据库连接、线程池、日志记录器等。 单例模式的核心思想是通…...

面试系列 - Java常见算法(一)

目录 一、排序算法 1、冒泡排序&#xff08;Bubble Sort&#xff09;&#xff1a; 2、快速排序&#xff08;Quick Sort&#xff09;&#xff1a; 二、查找算法 1、二分查找&#xff08;Binary Search&#xff09;&#xff1a; 三、 图算法 1、深度优先搜索&#xff08;De…...

Sentinel学习(1)——CAP理论,微服务中的雪崩问题,和Hystix的解决方案 Sentinel的相关概念 + 下载运行

前言 Sentinel 是面向分布式、多语言异构化服务架构的流量治理组件&#xff0c;主要以流量为切入点&#xff0c;从流量路由、流量控制、流量整形、熔断降级、系统自适应过载保护、热点流量防护等多个维度来帮助开发者保障微服务的稳定性。 本篇博客介绍CAP理论&#xff0c;微…...

C#学习 - 表达式、语句

表达式 定义 算法逻辑的最基本单元&#xff0c;表达一定的算法意图是由一个或多个操作数和零个或多个操作符组成的序列表达式功能是求值&#xff0c;得到的结果可能是一个值、对象、方法或名称空间因为操作符有优先级&#xff0c;所以表达式也有优先级 分类 一个值。表达式…...

VirtualBox 进入虚拟机后,鼠标出不来了

VirtualBox 进入虚拟机后&#xff0c;鼠标出不来了。 一般情况下&#xff0c;VirtualBox默认的鼠标切换快捷键是右边的Ctrl键。 如果按住右Ctrl键还是没有用&#xff0c;那应该是没有设置主机键。 设置方法&#xff1a; 打开VirtualBox的全局设定&#xff0c;找到热键&#xff…...

030-从零搭建微服务-消息队列(二)

写在最前 如果这个项目让你有所收获&#xff0c;记得 Star 关注哦&#xff0c;这对我是非常不错的鼓励与支持。 源码地址&#xff08;后端&#xff09;&#xff1a;mingyue: &#x1f389; 基于 Spring Boot、Spring Cloud & Alibaba 的分布式微服务架构基础服务中心 源…...

Docker从认识到实践再到底层原理(九)|Docker Compose 容器编排

前言 那么这里博主先安利一些干货满满的专栏了&#xff01; 首先是博主的高质量博客的汇总&#xff0c;这个专栏里面的博客&#xff0c;都是博主最最用心写的一部分&#xff0c;干货满满&#xff0c;希望对大家有帮助。 高质量博客汇总 然后就是博主最近最花时间的一个专栏…...

操作EXCEL计算3万条数据的NDVI并填入

Python操作EXCEL&#xff0c;计算3万条数据的NDVI并填入 问题描述 现在是有构建好了的查找表&#xff0c;不过构建了3万条数据&#xff0c;在excel中手动计算每行的NDVI值太麻烦了&#xff0c;也不会操作。 就试试python吧&#xff0c;毕竟python自动处理大型EXCEL数据很方便…...

Linux服务器安装Anaconda 配置远程jupyter lab使用虚拟环境

参考的博客&#xff1a; Linux服务器安装Anaconda 并配置远程jupyter lab anaconda配置远程访问jupyter&#xff0c;并创建虚拟环境 理解和创建&#xff1a;Anaconda、Jupyterlab、虚拟环境、Kernel 下边是正文了。 https://www.anaconda.com/download是官网网址&#xff0c;可…...

R语言实现随机生存森林(3)

常见问题解答 1、计算C指数 1-Error rate&#xff0c;或者 rsf.err <- get.cindex(yvar$Survival_months,yvar$OS,predictedrf.grow$predicted) 2、模型中predicted和predicted.oob区别 predicted和predicted.oob是两个不同的属性&#xff0c;它们分别表示模型的预测结果…...

WebPack-打包工具

从图中我们可以看出&#xff0c;Webpack 可以将多种静态资源 js、css、less 转换成一个静态文件&#xff0c;减少了页面的请求. 下面举个例子 &#xff1a; main.js 我们只命名导出一个变量 export const name"老六"index.js import { name } from "./tset/…...

CISSP学习笔记:PKI和密码学应用

第七章 PKI和密码学应用 7.1 非对称密码学 对称密码系统具有共享的秘钥系统&#xff0c;从而产生了安全秘钥分发的问题非对称密码学使用公钥和私钥对&#xff0c;无需支出复杂密码分发系统 7.1.1 公钥与私钥 7.1.2 RSA&#xff08;兼具加密和数字签名&#xff09; RSA算法…...

简述Java21新特性

Java21新特性 你发任你发我用Java8 不管Java更新了多少版本&#xff0c;我还是用Java8,因为在很多框架不知道支持不支持Java21&#xff0c;而且因为很多Jar包的版本冲突问题&#xff0c;所以我还是用Java8&#xff0c;但是对于新技术的了解是非常必要的。 Java 21是新推出的长…...

Composition API(常用部分)

1. Composition API(常用部分) 文档: ​ https://composition-api.vuejs.org/zh/api.html 1) setup 新的option, 所有的组合API函数都在此使用, 只在初始化时执行一次函数如果返回对象, 对象中的属性或方法, 模板中可以直接使用2) ref 作用: 定义一个数据的响应式语法: cons…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

【机器视觉】单目测距——运动结构恢复

ps&#xff1a;图是随便找的&#xff0c;为了凑个封面 前言 在前面对光流法进行进一步改进&#xff0c;希望将2D光流推广至3D场景流时&#xff0c;发现2D转3D过程中存在尺度歧义问题&#xff0c;需要补全摄像头拍摄图像中缺失的深度信息&#xff0c;否则解空间不收敛&#xf…...

智能在线客服平台:数字化时代企业连接用户的 AI 中枢

随着互联网技术的飞速发展&#xff0c;消费者期望能够随时随地与企业进行交流。在线客服平台作为连接企业与客户的重要桥梁&#xff0c;不仅优化了客户体验&#xff0c;还提升了企业的服务效率和市场竞争力。本文将探讨在线客服平台的重要性、技术进展、实际应用&#xff0c;并…...

MODBUS TCP转CANopen 技术赋能高效协同作业

在现代工业自动化领域&#xff0c;MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步&#xff0c;这两种通讯协议也正在被逐步融合&#xff0c;形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...

【2025年】解决Burpsuite抓不到https包的问题

环境&#xff1a;windows11 burpsuite:2025.5 在抓取https网站时&#xff0c;burpsuite抓取不到https数据包&#xff0c;只显示&#xff1a; 解决该问题只需如下三个步骤&#xff1a; 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...

Module Federation 和 Native Federation 的比较

前言 Module Federation 是 Webpack 5 引入的微前端架构方案&#xff0c;允许不同独立构建的应用在运行时动态共享模块。 Native Federation 是 Angular 官方基于 Module Federation 理念实现的专为 Angular 优化的微前端方案。 概念解析 Module Federation (模块联邦) Modul…...

算法笔记2

1.字符串拼接最好用StringBuilder&#xff0c;不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

QT3D学习笔记——圆台、圆锥

类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体&#xff08;对象或容器&#xff09;QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质&#xff08;定义颜色、反光等&#xff09;QFirstPersonC…...

Linux nano命令的基本使用

参考资料 GNU nanoを使いこなすnano基础 目录 一. 简介二. 文件打开2.1 普通方式打开文件2.2 只读方式打开文件 三. 文件查看3.1 打开文件时&#xff0c;显示行号3.2 翻页查看 四. 文件编辑4.1 Ctrl K 复制 和 Ctrl U 粘贴4.2 Alt/Esc U 撤回 五. 文件保存与退出5.1 Ctrl …...

Razor编程中@Html的方法使用大全

文章目录 1. 基础HTML辅助方法1.1 Html.ActionLink()1.2 Html.RouteLink()1.3 Html.Display() / Html.DisplayFor()1.4 Html.Editor() / Html.EditorFor()1.5 Html.Label() / Html.LabelFor()1.6 Html.TextBox() / Html.TextBoxFor() 2. 表单相关辅助方法2.1 Html.BeginForm() …...