java實現:對jar包中的配置檔案修改
阿新 • • 發佈:2019-01-03
注:只修改檔案,其他會被清空
package com.mtpc.admin.util; import java.io.*; import java.util.*; import java.util.jar.JarEntry; import java.util.jar.JarFile; import java.util.jar.JarOutputStream; public class JarUtil { /** * jarPath: jar包所在路徑 * jarFilePath: jar中想要修改檔案所在的路徑 * map: 要修改的內容 */ public static void main(String agrs[]) throws IOException { JarUtil jarUtil=new JarUtil(); Map map=new HashMap(); map.put("url","moTooling111"); map.put("username","cl"); map.put("password","321123"); jarUtil.change("H:\\mtpcbootPrivate\\target\\mtpc.jar","H:\\mtpcbootPrivate\\target\\mtpc.jar\\BOOT-INF\\classes\\application.yml",map); } /** * * @param jarPath * @param jarFilePath * @param map 修改的內容 * @return * @throws IOException */ public JarUtil change(String jarPath, String jarFilePath, Map map) throws IOException { if (jarPath != null && jarFilePath != null && map != null) { File file = new File(jarPath); JarFile jarFile = new JarFile(file);// 通過jar包的路徑 建立 jar包例項 JarEntry entry = jarFile .getJarEntry("BOOT-INF/classes/application.yml");// 通過某個檔案在jar包中的位置來獲取這個檔案 InputStream input = jarFile.getInputStream(entry); // 建立該檔案輸入流 List<JarEntry> lists = new LinkedList<>(); for (Enumeration<JarEntry> entrys = jarFile.entries(); entrys.hasMoreElements();) { JarEntry jarEntry = entrys.nextElement(); lists.add(jarEntry); } process(lists, entry, jarPath, jarFilePath, input, map); // 修改檔案內容 jarFile.close(); } return null; } /* 將jar中的yml檔案讀出並修改 */ private static void process(List<JarEntry> lists, JarEntry entry, String jarPath, String jarFilePath, InputStream input, Map map) throws IOException { InputStreamReader isr = new InputStreamReader(input); BufferedReader br = new BufferedReader(isr); StringBuffer buf = new StringBuffer(); String line = null; while ((line = br.readLine()) != null) { // 此處根據實際需要修改某些行的內容 if (line.trim().startsWith( "url:")) { buf.append("url: jdbc:mysql://192.168.2.186:3306/"+map.get("url")+"?useUnicode=true&characterEncoding=utf8&useSSL=false&tinyInt1isBit=true"); } else if (line.trim() .startsWith("username:")) { buf.append("username:"+map.get("username")); }else if (line.trim() .startsWith("password:")) { buf.append("password:"+map.get("password")); } // 如果不用修改, 則按原來的內容回寫 else { buf.append(line); } buf.append(System.getProperty("line.separator")); } //write(lists, entry, jarPath, buf.toString());// 將修改後的內容寫入jar包中的指定檔案 // write2JarFile(new File(jarPath),buf.toString().getBytes()); 拷貝jar包中所有檔案並修改jar包中的配置檔案 write2(jarPath, buf.toString()); //將jar中的配置檔案拷貝到指定目目錄下並進行修改 br.close(); } /** * 將yml拷貝到tempath目錄下 * @param jarFile 當前jar所在目錄 * @param writeBytes 要寫入的內容 */ private static void write2(String jarFile, String writeBytes) { OutputStreamWriter oStreamWriter = null; String tempPath = jarFile.substring(0, jarFile.lastIndexOf("/")) + "/BOOT-INF/classes/application.yml"; System.out.println(tempPath); try { //寫入並設定為UTF-8 oStreamWriter = new OutputStreamWriter(new FileOutputStream(tempPath), "utf-8"); oStreamWriter.append(writeBytes); oStreamWriter.flush(); oStreamWriter.close(); } catch (Exception e) { e.printStackTrace(); } } /** 將修改後的原寫入yml中 */ public static void write(List<JarEntry> lists, JarEntry entry, String jarPath, String content) throws IOException { JarOutputStream jos = null; FileOutputStream fos = new FileOutputStream(jarPath); jos = new JarOutputStream(fos); try { for (JarEntry je : lists) { JarEntry newEntry = new JarEntry(je.getName()); jos.putNextEntry(newEntry); if (je.getName().equals("BOOT-INF/classes/application.yml")) { jos.write(content.getBytes()); continue; } } // 將內容寫入檔案中 } catch (Exception e) { e.printStackTrace(); } finally { // 關閉流 if (jos != null) { try { jos.close(); } catch (IOException e) { jos = null; } } } } /** * 寫入jar檔案的話會將 jar檔案原來的內容統統抹掉!!切記!!~ */ private static void write2JarFile(File file, byte[] writeBytes) { String originalPath = file.getAbsolutePath(); /** 建立一個臨時檔案來做暫存,待一切操作完畢之後會將該檔案重新命名為原檔案的名稱(原檔案會被刪除掉)~ */ String tempPath = originalPath.substring(0, originalPath.length() - 4) + "new.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 中的每一個資料夾 每一個檔案 都是一個 jarEntry JarEntry 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); /** 如果當前已經處理到屬性檔案了,那麼將在 傳入的值 過的文字寫入到該屬性檔案~ */ if (je.getName().equals("BOOT-INF/classes/application.yml")) { jos.write(writeBytes); continue; } InputStream is = originalJar.getInputStream(je); byte[] bytes = inputStream2byteArray(is); is.close(); // 然後就是往entry中的jj.txt檔案中寫入內容 jos.write(bytes); } // 最後不能忘記關閉流 jos.close(); fos.close(); /** 刪除原始檔案,將新生成的檔案重新命名為原始檔案的名稱~ */ file.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; } }