日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

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

發布時間:2024/7/23 java 38 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java -uf_Java如何快速修改Jar包里的文件内容 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

需求背景:寫了一個實時讀取日志文件以及監控的小程序,打包成了Jar包可執行文件,通過我們的web主系統上傳到各個服務器,然后調用ssh命令執行。每次上傳前都要通過解壓縮軟件修改或者替換里面的配置文件,這樣感覺有點麻煩,就想辦法能不能通過程序動態生成配置文件,然后修改或者替換掉Jar包里的配置文件,最后再上傳到各個服務器去執行。

實現歷程:剛開始看了大量文章,整理出來了一個操作Jar包的工具類,用工具類里面的方法去修改一個30M左右的Jar包文件時,發現耗時竟然要7秒,而且修改Jar文件的方法確實有點復雜(這個可能需要開發JDK的專業人士提供簡單、高效的方法了),果斷忍受不了,然后想能不能通過其他的方法來實現。想到了一個方案,就是不通過java去修改Jar里的文件,而是用linux的Jar命令(當然也是通過java去調用linux命令),先解壓縮jar包,然后將動態生成的配置文件替換解壓縮包里的配置文件,最后再將目錄壓縮成Jar文件。經過測試,這樣大概需要4秒的時間,確實快了不少。想了很久也沒有想到其他更好的辦法,正打算實施的時候,看到了這條命令:jar uf test.jar manifest.mf ?-u 更新已存在的 JAR 文件包 (添加文件到 JAR 文件包中) ?-f 指定 JAR 文件名;瞬間來了靈感,直接調用這條命令不就OK了!通過這條命令幾秒鐘就輕輕松松搞定了,簡直是山窮水盡疑無路,柳暗花明又一村。

下面是我整理的操作Jar包的工具類(已經通過測試,可以拿去直接用),包括讀取Jar包的文件內容,遍歷 Jar包,修改 Jar包文件內容等操作,供大家參考。

packagecom.agent.util;importjava.io.BufferedReader;importjava.io.ByteArrayOutputStream;importjava.io.FileNotFoundException;importjava.io.FileOutputStream;importjava.io.IOException;importjava.io.InputStream;importjava.io.InputStreamReader;importjava.util.Enumeration;importjava.util.Iterator;importjava.util.Map;importjava.util.Set;importjava.util.TreeMap;importjava.util.jar.JarEntry;importjava.util.jar.JarFile;importjava.util.jar.JarOutputStream;public classJarUtil {/*** 讀取jar包所有的文件內容,顯示JAR文件內容列表

*@paramjarFileName

*@throwsIOException*/

public static void readJARList(String jarFilePath) throwsIOException {//創建JAR文件對象

JarFile jarFile = newJarFile(jarFilePath);//枚舉獲得JAR文件內的實體,即相對路徑

Enumeration en =jarFile.entries();

System.out.println("文件名\t文件大小\t壓縮后的大小");//遍歷顯示JAR文件中的內容信息

while(en.hasMoreElements()) {//調用方法顯示內容

process(en.nextElement());

}

}//顯示對象信息

private static voidprocess(Object obj) {//對象轉化成Jar對象

JarEntry entry =(JarEntry) obj;//文件名稱

String name =entry.getName();//文件大小

long size =entry.getSize();//壓縮后的大小

long compressedSize =entry.getCompressedSize();

System.out.println(name+ "\t" + size + "\t" +compressedSize);

}/*** 讀取jar包里面指定文件的內容

*@paramjarFileName jar包文件路徑

*@paramfileName 文件名

*@throwsIOException*/

public static void readJarFile(String jarFilePath,String fileName) throwsIOException{

JarFile jarFile= newJarFile(jarFilePath);

JarEntry entry=jarFile.getJarEntry(fileName);

InputStream input=jarFile.getInputStream(entry);

readFile(input);

jarFile.close();

}public static void readFile(InputStream input) throwsIOException{

InputStreamReader in= newInputStreamReader(input);

BufferedReader reader= newBufferedReader(in);

String line ;while((line = reader.readLine())!=null){

System.out.println(line);

}

reader.close();

}/*** 讀取流

*

*@paraminStream

*@return字節數組

*@throwsException*/

public static byte[] readStream(InputStream inStream) throwsException {

ByteArrayOutputStream outSteam= newByteArrayOutputStream();byte[] buffer = new byte[1024];int len = -1;while ((len = inStream.read(buffer)) != -1) {

outSteam.write(buffer,0, len);

}

outSteam.close();

inStream.close();returnoutSteam.toByteArray();

}/*** 修改Jar包里的文件或者添加文件

*@paramjarFile jar包路徑

*@paramentryName 要寫的文件名

*@paramdata 文件內容

*@throwsException*/

public static void writeJarFile(String jarFilePath,String entryName,byte[] data) throwsException{//1、首先將原Jar包里的所有內容讀取到內存里,用TreeMap保存

JarFile jarFile = newJarFile(jarFilePath);//可以保持排列的順序,所以用TreeMap 而不用HashMap

TreeMap tm = newTreeMap();

Enumeration es=jarFile.entries();while(es.hasMoreElements()){

JarEntry je=(JarEntry)es.nextElement();byte[] b =readStream(jarFile.getInputStream(je));

tm.put(je.getName(),b);

}

JarOutputStream jos= new JarOutputStream(newFileOutputStream(jarFilePath));

Iterator it=tm.entrySet().iterator();boolean has = false;//2、將TreeMap重新寫到原jar里,如果TreeMap里已經有entryName文件那么覆蓋,否則在最后添加

while(it.hasNext()){

Map.Entry item=(Map.Entry) it.next();

String name=(String)item.getKey();

JarEntry entry= newJarEntry(name);

jos.putNextEntry(entry);byte[] temp ;if(name.equals(entryName)){//覆蓋

temp =data;

has= true;

}else{

temp= (byte[])item.getValue();

}

jos.write(temp,0, temp.length);

}if(!has){//最后添加

JarEntry newEntry = newJarEntry(entryName);

jos.putNextEntry(newEntry);

jos.write(data,0, data.length);

}

jos.finish();

jos.close();

}/*** 測試案例

*@paramargs

*@throwsException*/

public static void main(String args[]) throwsException{// readJarFile("D:\\esjavaclient-0.0.1-SNAPSHOT.jar","es-info.properties");

String data= "helloBabydsafsadfasdfsdafsdgasdgweqtqwegtqwfwefasdfasfadfasf";long start =System.currentTimeMillis();

writeJarFile("D:\\esjavaclient-0.0.1-SNAPSHOT.jar","es-info.properties",data.getBytes());long end =System.currentTimeMillis();

System.out.println(end-start);

readJarFile("D:\\esjavaclient-0.0.1-SNAPSHOT.jar","es-info.properties");

}

}

View Code

上面有個測試案例,測試讀取其中一個配置文件,然后修改這個文件,最后再讀取出來。 一個30M左右的Jar包文件耗時7秒多,實在忍受不了。網上找了很多文章,同時看了Zip相關的源碼,也木有找到可以直接修改Jar包文件內容的方法。 最后只能另辟蹊徑,找到了一個執行效率非常快的方法。

關于工具類沒有刪除文件的方法,大家根據修改的方法稍微改造一下即可。

工具類參考的博客:

如何快速修改Jar包里的文件內容:

貼出來我巧妙實現的代碼:(如果不知道Java 如何調用linux命令的同學,請先補習一下這方面的知識)

String cmd = "jar uf esjavaclient-0.0.1-SNAPSHOT.jar config.properties";

String[] cmds = {"/bin/sh","-c",cmd};

Process pro;

try{

pro =Runtime.getRuntime().exec(cmds);

pro.waitFor();

InputStream in =pro.getInputStream();

BufferedReader read = new BufferedReader(newInputStreamReader(in));

String line = null;

while((line = read.readLine())!=null){

System.out.println(line);

}

} catch(Exception e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

通過執行這條條命令,就可以很快將我們生成的配置文件config.properties覆蓋掉Jar里的文件,從而達到修改的目的。

總結:如果Jar包里的文件不大的話,完全可以用工具類提供的方法去操作Jar包。比較大的話,修改Jar包的方法,推薦用我那個巧妙的方法。

最后:給開發JDK的專業人士提點建議,關于操作壓縮包這方面的API還不夠強大,希望后續可以完善一下

總結

以上是生活随笔為你收集整理的java -uf_Java如何快速修改Jar包里的文件内容的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。