关于文件夹内容变动对比

现在手机程序很多支持省流量更新,也就是更新时只把改动的文件替换掉。要做到这样,就得能够对两次的文件夹进行对比,于是写了下面对比代码。

package mapcomp.comp;

import java.io.File;
import java.io.FileInputStream;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class Comp {

    public static void main(String[] args) {
        comp("E:/comp/po1", "E:/comp/po2");
        
    }
    
    public static void comp(String path1, String path2){
        List<String> list1 = new ArrayList<String>();
        getFileNameList(new File(path1), list1);
        Map<String, FileInfo> map1 = getFileInfoMap(path1, list1, true);
        
        List<String> list2 = new ArrayList<String>();
        getFileNameList(new File(path2), list2);
        Map<String, FileInfo> map2 = getFileInfoMap(path2, list2, false);    //MD5计算比较费时,先对比大小,一样再比较md5
        
        Set<String> set1_add = new HashSet<String>(map1.keySet());
        Set<String> set2_remove = new HashSet<String>(map2.keySet());
        Set<String> set3_common = new HashSet<String>(map1.keySet());
        set3_common.addAll(map2.keySet());
        
        set1_add.removeAll(map2.keySet());
        System.out.println("新增的文件有:" + set1_add.toString());
        set2_remove.removeAll(map1.keySet());
        System.out.println("移除的文件有:" + set2_remove.toString());
        set3_common.removeAll(set1_add);
        set3_common.removeAll(set2_remove);
        System.out.println("保留的文件有:" + set3_common.toString());
        //接下来对比保留的文件
        //先对比大小,若不一样则肯定不一样,一样然后对比md5
        List<String> unSame = new ArrayList<String>();
        for(String ph : set3_common){
            FileInfo info1 = map1.get(ph);
            FileInfo info2 = map2.get(ph);
            if(info1.length != info2.length){
                unSame.add(ph);
            }else{
                info2.md5 = getFileMD5(new File(path2 + ph));
                if(!info1.md5.equals(info2.md5)){
                    unSame.add(ph);
                }
            }
        }
        System.out.println("不一样的文件有:" + unSame.toString());
    }
    
    //把文件信息整理放到Map
    private static Map<String, FileInfo> getFileInfoMap(String rootPath, List<String> list1, boolean md5) {
        Map<String, FileInfo> map = new HashMap<String, FileInfo>();
        for(String path : list1){
            FileInfo info = new FileInfo();
            File file = new File(path);
            info.filePath = file.getAbsolutePath().substring(rootPath.length());
            info.length = file.length();
            if(md5){
                info.md5 = getFileMD5(file);
            }
            map.put(info.filePath, info);
        }
        return map;
    }
    
    public static String getFileMD5(File file) {  
        if (!file.exists() || !file.isFile()) {  
            return null;  
        }  
        MessageDigest digest = null;  
        FileInputStream in = null;  
        byte buffer[] = new byte[1024];  
        int len;  
        try {  
            digest = MessageDigest.getInstance("MD5");  
            in = new FileInputStream(file);  
            while ((len = in.read(buffer, 0, 1024)) != -1) {  
                digest.update(buffer, 0, len);  
            }  
            in.close();  
        } catch (Exception e) {  
            e.printStackTrace();  
            return null;  
        }  
        BigInteger bigInt = new BigInteger(1, digest.digest());  
        return bigInt.toString(16);  
    }

    //获取所有文件
    public static void getFileNameList(File folder, List<String> list){
        File[] listFiles = folder.listFiles();
        for(File f : listFiles){
            if(f.isDirectory()){
                getFileNameList(f, list);
            }else{
                list.add(f.getAbsolutePath());
            }
        }
    }
    
}

class FileInfo{
    
    public String filePath;
    public long length;
    public String md5;
    
}

这只是大致思路,可以在把新代码作为path1,检出的信息以某种格式作为文件,在需要更新升级的地方进行同样的整理对比,然后把需要更新的信息传送回来,然后发送过去替换。当年在东软那个项目升级完全可以这样来,竟然采取的是全部文件打包发送替换,一个项目差不多一个g,给服务器增加了巨大压力。

原文地址:https://www.cnblogs.com/zhongshiqiang/p/7117846.html