关于文件夹内容变动对比

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

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

时间: 2024-08-07 09:53:49

关于文件夹内容变动对比的相关文章

Winform文件夹内容同步更新、备份、日志、恢复

相信大家做项目或者处理文件时候经常要用到备份的功能,这里给大家做一个可以同步更新文件夹内容并且备份的Winform程序,目前地址路径在App.Config文件里面设置,如需更改直接用记事本编辑即可,下面放代码和截图. 1.CS代码: using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Li

取得文件夹内容信息

翻译自MSDN 2005 -> Win32 和 COM 开发 -> User Interface -> Windows User Experience -> Windows Shell -> Shell Programmer's Guide -> Shell Basics -> Shell Basics: Programming the Shell -> Getting Information About the Contents of a Folder G

PHP批量清空删除指定文件夹内容

PHP批量清空删除指定文件夹内容: cleancache.php <?php // 清文件缓存 $dirs = array( realpath(dirname(__FILE__) . '/../data/cache_data'), realpath(dirname(__FILE__) . '/../data/cache_file'), realpath(dirname(__FILE__) . '/../data/cache_view') ); // 清理缓存 foreach($dirs as $

Beyond Compare比较文件夹内容

如果想要Beyond Compare支持文件夹以及各层文件内容的比较,是需要设置规则的,否则会困惑于文件夹内容比较为何不好使. 1. 新建文件夹比较,点击“编辑默认” 2. 设置比较选项  3. 输入比较的文件夹路径即可(下面只显示有差别的文件) 如果需要所有子文件夹展开,点击图标“展开”即可 如果需要导出比较结果,“会话”=> “文件夹比较 报告” 原文地址:https://www.cnblogs.com/roostinghawk/p/12267576.html

Windows 下自动同步文件夹内容到另一个文件夹下

实现windows 使用bat脚本文件,复制文件夹到另一个盘,参考如下代码:/y是可以不显示:提示你需要覆盖一个文件,如下图: bat文件内容为 @echo off echo "使用bat脚本来复制文件夹和文件" echo. xcopy H:\ceshi\*.* F:\autotomcat\ /s /e /c /y /h /r pause 把bat文件放到除了C盘的其他盘下 提示   C盘下的文件操作一般都需要管理员权限才可以 下面开始配置计划任务自动执行 点击  开始----管理工具

计算沙盒下文件夹内容大小 清空沙盒 文件 目录

1 +(float)fileSizeForDir:(NSString*)path//计算文件夹下文件的总大小 2 3 { 4 5 NSFileManager *fileManager = [[NSFileManager alloc] init]; 6 7 float size =0; 8 9 NSArray* array = [fileManager contentsOfDirectoryAtPath:path error:nil]; 10 11 for(int i = 0; i<[array

shell脚本复制文件夹内容到另外的文件夹,如果存在则自动备份

有时我们需要将一个文件夹覆盖到我们的工作目录,但需要自动备份已经存在的文件,一个一个去备份太麻烦了,全部备份又没有必要.shell脚本可以很好滴完成这个任务.原文链接http://back.zhizhi123.com/?p=85 #!/bin/sh upload_dir=/alidata/www/sh/useful-shell-script/upload/ www_dir=/alidata/www/sh/useful-shell-script/www/ backexist() { filelis

用JUNCTION映射文件夹内容 解决多系统跑同一个虚拟机而共享文件夹路径不同的问题

事情由来: 某机器安装了俩系统,WIN7X64用来玩PC游戏,WIN2012R2用来工作,系统分别在两个不同的分区,但进入到系统后,两个系统的系统盘都是C盘.换句话说,在WIN7里,分区1是C盘,分区2是D盘,但是到了WIN2012R2里,分区2是C盘,分区1是D盘.这么导致的后果是,虚拟机里映射的盘符,在另外一个系统就不可用了.比如我在WIN7里,把C:\TEST映射到了“NET虚拟机”的共享文件夹,但是到了WIN2012R2里,C:\TEST的实际路径是D:\TEST,这时候在“NET虚拟机

查看Android模拟器的SDCard文件夹内容

可以通过DDMS查看: 一般在Eclipse的菜单栏(右上角)可以找到,如果没有,在图标Java左边的按钮选择添加 在DDMS可以直接添加文件夹和文件,但不能删除文件夹和文件,需要通过adb shell方式删除 删除命令为rm -r 文件夹名或文件名