开发这个小工具的初衷是为了修改工具 jar 包中的配置文件

本来打算将这个功能集成到 工具 jar 包自身

但是这里貌似有点儿问题,因为该 jar 包文件当前正在被 java 虚拟机使用,所以无法对其进行修改操作~

这里我有点儿疑惑,难道不是将 jar 包整个加载到内存中去了么?

为什么磁盘上的物理文件还是被牢牢锁定?mac上是这样,windows里面也是这样,应该有点儿蹊跷,不深究了~

本示例主要包含了以下知识点:

1。遍历 jar 文件中的所有文件(jar包实际上就是zip压缩包,没什么神奇的)

2。就像读取磁盘中的其他文件一样,对jar执行 读入和写出操作

3。将 jar文件中的某个文件读到 swing的 jTextArea 里面,在退出的时候将修改过的文字覆盖回原文件

4。将InputStream 安全的转换为 byte[] 数组

5。拖拽取得文件的完整路径

下面直接上代码实例:

package org.bruce.vertices.extra;import java.awt.Toolkit;
import java.awt.datatransfer.DataFlavor;
import java.awt.dnd.DnDConstants;
import java.awt.dnd.DropTarget;
import java.awt.dnd.DropTargetAdapter;
import java.awt.dnd.DropTargetDropEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
import java.util.zip.ZipEntry;import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;/*** @author Bruce Yang* PS:本示例专门用于编辑我自己制作的一个 jar 文件的属性文件,* 是不具备通用性的。不过源码既然放出,变得适应各种不同的需求,自然是不存在什么难题~* 为了方便地提供最基本的适应需求,主要将 configPath 修改为各自 jar包中 配置文件的 classPath 即可~* 一言以蔽之:* 这个工具主要起到了快捷修改jar文件中某个配置文件的作用~* 遗憾的是,还有一些需求我没能完成,诸如怎么将JTextArea中属性文件的内容修改的和elcipse中打开属性文件一样,* 那样的话,‘=’,‘true’,‘false’,整数等值具备了不同高亮颜色的话,看起来就舒服多了~* 各位有兴趣可以试试,据我目前所知,JTextPane貌似更加适合做这个功能,但是有些小细节我不明了。。。* 如有对这个同样感兴趣且扩展出上述“高亮”功能的大侠,还请给我邮一份,不甚感激!* 在下邮箱:bestfighter@yeah.net*/
public class JarCfgEditor extends JFrame {private static final long serialVersionUID = -7044615012246731094L;public String configPath = "org/bruce/vertices/resources/DefaultCfg.properties";public static final int CONSOLE_DIALOG_WIDTH = 500;public static final int CONSOLE_DIALOG_HEIGHT = 400;private JScrollPane jsp;private JTextArea jta;private File original;private void initMemberVariables() {jta = new JTextArea();jsp = new JScrollPane();}public JarCfgEditor() {super();this.initMemberVariables();this.setSize(500, 400);jsp.setViewportView(jta);this.add(jsp);JScrollBar jsb = jsp.getVerticalScrollBar();jsb.setValue(jsb.getMaximum()); int screenWidth = Toolkit.getDefaultToolkit().getScreenSize().width;int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;this.setLocation((screenWidth-CONSOLE_DIALOG_WIDTH)/2, (screenHeight-CONSOLE_DIALOG_HEIGHT)/2);/** 关闭的时候将修改过的属性覆盖到 jar 里面的属性配置文件~ */this.addWindowListener(new WindowAdapter() {public void windowClosing(WindowEvent arg0) {if(original != null) {write2JarFile();}System.exit(0);}});new DropTarget(jta, DnDConstants.ACTION_COPY_OR_MOVE, new MyDropTargetListener(this));this.setTitle("CfgViewer0.1");this.setVisible(true);}/*** 写入jar文件的话会将 jar文件原来的内容统统抹掉!!切记!!~*/private void write2JarFile() {String originalPath = original.getAbsolutePath();/** 创建一个临时文件来做暂存,待一切操作完毕之后会将该文件重命名为原文件的名称(原文件会被删除掉)~ */String tempPath = originalPath.substring(0, originalPath.length()-4) + "_temp.jar";System.out.println(tempPath);JarFile originalJar = null;try {originalJar = new JarFile(originalPath);} catch (IOException e1) {e1.printStackTrace();}List<JarEntry> lists = new LinkedList<JarEntry>();for(Enumeration<JarEntry> entrys = originalJar.entries(); entrys.hasMoreElements();) {JarEntry jarEntry = entrys.nextElement();
//            System.out.println(jarEntry.getName());lists.add(jarEntry);}// 定义一个 jaroutputstream 流File handled = new File(tempPath);JarOutputStream jos = null;try {FileOutputStream fos = new FileOutputStream(handled);jos = new JarOutputStream(fos);/*** 将源文件中的内容复制过来~* 可以利用循环将一个文件夹中的文件都写入jar包中 其实很简单*/for(JarEntry je : lists) {// jar 中的每一个文件夹 每一个文件 都是一个 jarEntryJarEntry newEntry = new JarEntry(je.getName());//                newEntry.setComment(je.getComment());
//              newEntry.setCompressedSize(je.getCompressedSize());
//              newEntry.setCrc(je.getCrc());
//              newEntry.setExtra(je.getExtra());
//              newEntry.setMethod(je.getMethod());
//              newEntry.setTime(je.getTime());
//              System.out.println(je.getAttributes());/** 这句代码有问题,会导致将jar包重命名为zip包之后无法解压缩~ */
//              newEntry.setSize(je.getSize());// 表示将该entry写入jar文件中 也就是创建该文件夹和文件jos.putNextEntry(newEntry);/** 如果当前已经处理到属性文件了,那么将在 JTextArea 中编辑过的文本写入到该属性文件~ */if(je.getName().equals(configPath)) {jos.write(jta.getText().getBytes());continue;}InputStream is = originalJar.getInputStream(je);byte[] bytes = inputStream2byteArray(is);is.close();// 然后就是往entry中的jj.txt文件中写入内容jos.write(bytes);}// 最后不能忘记关闭流jos.close();fos.close();/** 删除原始文件,将新生成的文件重命名为原始文件的名称~ */original.delete();handled.renameTo(new File(originalPath));} catch (Exception e) {e.printStackTrace();}}/*** InputStream 转 byte[]~* @param is* @return*/public static byte[] inputStream2byteArray(InputStream is) {ByteArrayOutputStream baos = new ByteArrayOutputStream();int i;try {while((i = is.read()) != -1) {baos.write(i);}baos.close();} catch (IOException e) {e.printStackTrace();}byte[] bytes = baos.toByteArray();return bytes;}/** getters && setters~ */public JTextArea getJta() {return jta;}public void setJta(JTextArea jta) {this.jta = jta;}public File getJarFile() {return original;}public void setJarFile(File jarFile) {this.original = jarFile;}/*** 主方法~* @param args*/public static void main(String[] args) {new JarCfgEditor();}
}/*** @author Bruce Yang* 拖拽监听~*/
class MyDropTargetListener extends DropTargetAdapter {private JarCfgEditor jce;public MyDropTargetListener(JarCfgEditor jce) {this.jce = jce;}@Override@SuppressWarnings("unchecked")public void drop(DropTargetDropEvent event) {if (event.isDataFlavorSupported(DataFlavor.javaFileListFlavor)) {event.acceptDrop(DnDConstants.ACTION_COPY_OR_MOVE);DataFlavor df = DataFlavor.javaFileListFlavor;List<File> list = null;try {list = (List<File>)(event.getTransferable().getTransferData(df));} catch (Exception e) {e.printStackTrace();}Iterator<File> iterator = list.iterator();while (iterator.hasNext()) {File file = iterator.next();if(file.exists() && file.isFile()) {String filePath = file.getAbsolutePath();if(filePath == null || filePath.equals("")) {System.out.println("文件名为 null 或为 \"\"~");break;}if(!filePath.contains("GetVerticesMVC") || !filePath.endsWith(".jar")) {String str = "此工具专门为 GetVerticesMVC 设计,不通用!! 请注意!!";JOptionPane.showMessageDialog(null, str);break;}System.out.println("jarFilePath=" + filePath);jce.setJarFile(file);JarFile jarFile = null;try {jarFile = new JarFile(filePath);ZipEntry entry = jarFile.getEntry(jce.configPath);if(entry == null) {System.out.println(jce.configPath+"路径所代表的文件不存在!读取失败~");// 安全起见,将 jarFile 置为 null,这样在关闭窗口的时候将不会执行收尾操作~jce.setJarFile(null);break;}//获取到inputstream了 就相当简单了InputStream is = jarFile.getInputStream(entry);byte[] bytes = JarCfgEditor.inputStream2byteArray(is);String cfgStr = new String(bytes);jce.getJta().setText(cfgStr);} catch (IOException e) {e.printStackTrace();}}// 一次只能处理一个,要避免处理多个的情况,因此 break 跳出~break;}event.dropComplete(true);} else {event.rejectDrop();}}
}

转载于:https://www.cnblogs.com/yang3wei/archive/2012/04/06/2739796.html

java 修改 jar 包文件内容的一个实例相关推荐

  1. java修改jar包

    1.vim编辑的方式修改 可以使用vim xxx.jar的方式列出jar包文件内的目录,然后出入/来搜索我们要编辑的文件名, 定位后回车即可,然后按i编辑, :wq保存 2.jar命令先提取要更改的文 ...

  2. 修改jar包文件,重新打包jar

    一.网上搜到的下列替换方案都不行: 1.直接用WinRAR拖拽替换jar包内文件 失败,报错:压缩文件已损坏. 我以前替换成功过,但是启动的时候报错.这种方式可能会伤害到jar包的一些标识. 只适合z ...

  3. 修改android.jar教程,Android修改jar包文件

    1.Android studio中新建java文件,取和将要修改的文件相同的文件名,把class文件中代码复制过去,修改需要改动的代码 2.新建txt文件,将新建的Java文件按照依赖关系将路经添加到 ...

  4. java -uf_Java如何快速修改Jar包里的文件内容

    需求背景:写了一个实时读取日志文件以及监控的小程序,打包成了Jar包可执行文件,通过我们的web主系统上传到各个服务器,然后调用ssh命令执行.每次上传前都要通过解压缩软件修改或者替换里面的配置文件, ...

  5. java 单开程序_java生成jar包并且单进程运行的实例

    java文件打包jar运行 有效步骤: 1.cmd 到当前目录(默认包主类所在目录为例) set classpath = 默认包主类所在目录 2.javac 主类名.java 3.java 主类名 4 ...

  6. gradle 修改java代码_自定义一个gradle插件动态修改jar包Class文件

    动态修改jar包中的class文件,预埋占位符字符串,在编译代码时动态植入要修改的值.记录一下整个过程及踩过的坑. 创建一个Android项目,再创建一个Android library,删掉里面所有代 ...

  7. java bat 运行 jar文件_运行bat文件启动java的jar且不弹出DOS窗口,后台运行java的jar包...

    本文主要是将java的jar包启动的cmd命令添加到bat文件来执行,且不弹出DOS窗口,也就是后台运行java的jar包. 这里以win10为例 1.新建 一个txt文件,在文件添加以下内容.其中E ...

  8. java package 目录_修改jar包package目录结构操作方法

    本文将为您描述修改jar包package目录结构操作方法,具体操作过程: 开发中会遇到用第三方的jar包,有时候会出现不同的jar包,包名一致的情况,这就会引发运行时异常,找不到相应的jar包. 这种 ...

  9. jd+jbe修改jar包中class文件

    有时候从网上下的java demo中,有的是发布后的环境,所以只有jar包信息,没有对应的源码,我们要把其中的信息修改下,所以就需要我们本文中提到的直接修改java class信息.参考网上资料好,赶 ...

最新文章

  1. 5G NGC — CAPIF 网络能力开放框架
  2. 【转载】突然觉得今年的时间过得太快了,不知不觉中还剩下四个多月就步入2017年了,回首一下,好像什么都还没做呢。...
  3. 原生js cookie本地存储
  4. C++ 类和对象(二):构造函数、析构函数、拷贝构造函数、运算符重载
  5. 3dContactPointAnnotationTool开发日志(二十)
  6. QT-qevent 事件的accept()和ignore()
  7. Hibernate 发展之路
  8. 使用Jexus 容器化您的 Blazor 应用程序
  9. 用于zsh的高亮插件 zsh-syntax-highlighting
  10. 前端学习(490):javascript实现
  11. 作者:Gopakumar Gopalakrishnan,男,印度科技大学管理学博士,印孚瑟斯技术有限公司高级研究科学家。...
  12. AGC018F. Two Trees
  13. 【深度优先搜索】牛客网:剪绳子
  14. 10截图时屏幕变大_解锁电脑更多的截屏姿势:Win 10中自带的七种截图方法
  15. [NAACL18]What's Going On in Neural Constituency Parsers? An Analysis(神经成分句法分析器的一些分析)...
  16. 2018美国基金业年鉴-数据图表简版
  17. lockdir 密码破解
  18. 如何爬取中国近十年的GDP,对数据进行处理,并写入csv文件?
  19. PyautoGui常用教程(鼠标、键盘)
  20. Nelder-Mead算法在Matlab中的实现

热门文章

  1. redis tomcat session
  2. Red Hat 8.0中设置光盘为软件源
  3. snake4444勒索病毒成功处理教程方法工具达康解密金蝶/用友数据库sql后缀snake4444...
  4. zooland 新开源的RPC项目,希望大家在开发的微服务的时候多一种选择,让微服务开发简单,并且容易上手。...
  5. Promise 原理解析与实现(遵循Promise/A+规范)
  6. 制作简单的WIFI干扰器
  7. 云计算时代企业内部IT人员的新定位
  8. Web优化 --利用css sprites降低图片请求
  9. Iterm2的一些好用法
  10. PHP的钩子实现解析