1. 程式人生 > >java實現:對jar包中的配置檔案修改

java實現:對jar包中的配置檔案修改

注:只修改檔案,其他會被清空 

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;
    }

}