標籤:java
- 0x00 前言
之前工作的時候,經常會有客戶提交BUG或者新增一個功能等需求。於是我就會在我本地修改代碼,然後再打包替換客戶的項目。比較麻煩的是,每次更新都需要去SVN看看都改了哪些檔案,新增了哪些檔案,一個一個去找,然後打包,給客戶更新,有些時候一不小心就漏了或者搞錯了,非常的煩。其實我一直都想做的事情就是,寫一個程式,讓程式去實現對比新舊兩個項目,然後把新的項目多出來的檔案或者變更過的檔案複製出來,這樣就能省去我好多工作,主要是不用人工一個個的去比對。。 太煩了。
- 0x01 思路
1. 首先,我需要比較兩個項目。那麼怎樣才算我需要進行打包給客戶更新的檔案呢?這有兩種情況:
① 新增的檔案。
② 修改過的檔案。
③ 刪除的檔案。
2. 接下來肯定是要用到commons-io的包了,需要先去判斷是否新的檔案夾中的某個檔案是否在舊的檔案夾中存在,如果不存在,就是新增的;如果存在,那就需要比較兩個檔案是否一樣的了,這裡我們用到了MD5,通過計算兩個檔案的MD5值來實現比較兩個檔案是否一樣。
- 0x02 代碼
MD5演算法類,這裡引用了David的代碼 http://blog.csdn.net/zdwzzu2006/article/details/8064960
package net.wechance.incrementalupdatetool;import org.apache.commons.codec.binary.Hex;import org.apache.commons.codec.digest.DigestUtils;import java.io.File;import java.io.FileInputStream;import java.io.FileNotFoundException;import java.io.IOException;import java.security.MessageDigest;import java.security.NoSuchAlgorithmException;/** * 計算大檔案MD5 * David 2012-10-12 */public class CheckMD5 { static MessageDigest MD5 = null; static { try { MD5 = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException ne) { ne.printStackTrace(); } } /** * 對一個檔案擷取md5值 * @return md5串 */ public static String getMD5(File file) { FileInputStream fileInputStream = null; try { fileInputStream = new FileInputStream(file); byte[] buffer = new byte[8192]; int length; while ((length = fileInputStream.read(buffer)) != -1) { MD5.update(buffer, 0, length); } return new String(Hex.encodeHex(MD5.digest())); } catch (FileNotFoundException e) { e.printStackTrace(); return null; } catch (IOException e) { e.printStackTrace(); return null; } finally { try { if (fileInputStream != null) fileInputStream.close(); } catch (IOException e) { e.printStackTrace(); } } } /** * 求一個字串的md5值 * @param target 字串 * @return md5 value */ public static String MD5(String target) { return DigestUtils.md5Hex(target); }}
主方法類
package net.wechance.incrementalupdatetool;import org.apache.commons.io.FileUtils;import org.apache.commons.lang3.StringUtils;import java.io.File;import java.io.IOException;import java.io.InputStream;import java.util.ArrayList;import java.util.Iterator;import java.util.List;import java.util.Properties;/** * 主方法 * Created by William on 2015/7/10. */public class Main { private static String oldPath = ""; // 舊路徑 private static String newPath = ""; // 新路徑 private static String outPath = ""; // 輸出路徑 static { Properties prop = new Properties(); InputStream in = Object.class.getResourceAsStream("/config.properties"); try { prop.load(in); oldPath = prop.getProperty("oldPath").trim(); newPath = prop.getProperty("newPath").trim(); outPath = prop.getProperty("outPath").trim(); } catch (IOException e) { e.printStackTrace(); } } private static void checkFile() { } public static void main(String[] args) { System.out.println("---------------------------------------"); System.out.println("===> 程式已啟動"); System.out.println("===> 正在遍曆檔案夾 " + newPath); // 遍曆新檔案目錄 Iterator iterator = FileUtils.iterateFiles(new File(newPath), null, true); // 遍曆舊檔案目錄 Iterator iterator1 = FileUtils.iterateFiles(new File(oldPath), null, true); // 用於接收被刪除的目錄 List<String> deleteFiles = new ArrayList<String>(); System.out.println("===> 遍曆完成,開始執行分析"); long startTime = System.currentTimeMillis(); //擷取開始時間 try { // 遍曆比較新舊目錄 // 1. 如果檔案不存在,則說明是新增的檔案,複製該檔案到輸出路徑 // 2. 如果MD5值不一樣,則檔案被修改,複製該檔案到輸出路徑 while (iterator.hasNext()) { // 新檔案路徑 String nPathStr = iterator.next().toString(); File newFile = new File(nPathStr); // 舊檔案路徑 File oldFile = new File(nPathStr.replace(newPath, oldPath)); //System.out.println("===> 正在分析 " + nPathStr); // 判斷檔案是否存在 if (!oldFile.exists()) { File outFile = new File(nPathStr.replace(newPath, outPath)); FileUtils.copyFile(newFile, outFile); System.out.println("===> 已找到新增檔案 "); System.out.println("======> 複製檔案 " + outFile.toString()); System.out.println("Done."); System.out.println(); } else { // MD5校正 // 如果不相同,則copy到輸出路徑 String newMD5 = CheckMD5.getMD5(newFile); String oldMD5 = CheckMD5.getMD5(oldFile); if (!StringUtils.equals( newMD5, oldMD5 )) { File outFile = new File(nPathStr.replace(newPath, outPath)); FileUtils.copyFile(newFile, outFile); System.out.println("===> 已找到修改檔案 "); System.out.println("======> 新檔案 " + newFile + " (MD5: " + newMD5 + " )"); System.out.println("======> 舊檔案 " + oldFile + " (MD5: " + oldMD5 + " )"); System.out.println("======> 複製檔案 " + outFile.toString()); System.out.println("Done."); System.out.println(); } } } // 遍曆舊的檔案目錄 // 主要是用於尋找被刪除的檔案 System.out.println("===> 已找到刪除檔案 "); while (iterator1.hasNext()) { // 舊檔案路徑 String oPathStr = iterator1.next().toString(); // 新檔案路徑 File newFile = new File(oPathStr.replace(oldPath, newPath)); if (!newFile.exists()) { deleteFiles.add(oPathStr); System.out.println("======> 檔案路徑 " + oPathStr); } } } catch (Exception e) { System.err.println("發生異常!"); } long endTime=System.currentTimeMillis(); //擷取結束時間 System.out.println(); System.out.println("分析完成 耗時:" + ((endTime-startTime) / 1000) + "s"); System.out.println("輸出路徑:" + outPath); System.out.println("---------------------------------------"); }}
config.properties
#舊路徑oldPath=F:\\test\\oldPath#新路徑newPath=F:\\test\\newPath#輸出路徑outPath=F:\\test\\outPath
- 0x03 總結
最後,對項目進行測試。
舊檔案夾
新檔案夾
輸出檔案夾
控制台
好啦。到此就完工啦。湊合用,可以考慮把它做成一個GUI。可以滑鼠點點選擇兩個對比的目錄以及輸出的目錄。
著作權聲明:本文為博主原創文章,未經博主允許不得轉載。
使用JAVA實現比較兩個檔案夾下的檔案新增和修改情況,並複製到新的目錄(實現累加式更新項目)