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

  • 相关阅读:
    unexpected inconsistency;run fsck manually esxi断电后虚拟机启动故障
    centos 安装mysql 5.7
    centos 7 卸载mysql
    centos7 在线安装mysql5.6,客户端远程连接mysql
    ubuntu 14.04配置ip和dns
    centos7 上搭建mqtt服务
    windows eclipse IDE打开当前类所在文件路径
    git 在非空文件夹clone新项目
    eclipse中java build path下 allow output folders for source folders 无法勾选,该如何解决 eclipse中java build path下 allow output folders for source folders 无法勾选,
    Eclipse Kepler中配置JadClipse
  • 原文地址:https://www.cnblogs.com/zhongshiqiang/p/7117846.html
Copyright © 2011-2022 走看看