zoukankan      html  css  js  c++  java
  • 关于文件夹内容变动对比

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

    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,给服务器增加了巨大压力。

  • 相关阅读:
    java、asp.net 通用分页码函数
    SQL
    go build 参数
    alertmanager报错Failed to get final advertise address: No private IP address found, and explicit IP not provided"
    go语言三个点的用法
    CDH6.2安装
    python之链表
    jenkins触发构建后一直重复构建
    ansible远程执行寻找不到环境变量问题
    Python3之harbor sdk api
  • 原文地址:https://www.cnblogs.com/zhongshiqiang/p/7117846.html
Copyright © 2011-2022 走看看