• 编写一个diff工具,用于判断两个目录下所有的改动--3.0版本


    没心情优化代码了,就先这样吧

      1 package comcollection.test;
      2 
      3 import java.io.BufferedInputStream;
      4 import java.io.File;
      5 import java.io.FileInputStream;
      6 import java.io.FileOutputStream;
      7 import java.io.IOException;
      8 import java.io.InputStream;
      9 import java.io.OutputStream;
     10 import java.nio.channels.FileChannel;
     11 import java.text.SimpleDateFormat;
     12 import java.util.ArrayList;
     13 import java.util.Date;
     14 import java.util.HashMap;
     15 import java.util.List;
     16 import java.util.Map;
     17 import java.util.zip.CRC32;
     18 
     19 import org.apache.commons.io.FileUtils;
     20 
     21 /**
     22  * 
     23  * 1.有A和B两个目录,目录所在位置及层级均不确定
     24  * 2.需要以B为基准找出两个目录中所有有改动的文件(文件或内容增加、修改、删除),将有改动的文件放入第三个目录中,层级结构与原目录相同
     25  * 3.将所有新增与更新信息记录到更新日志文件中 
     26  * 4.将删除信息单独记录到删除日志文件中 
     27  * 5.每次执行diff工具需要生成一个新的以日期命名的目录存放文件
     28  */
     29 
     30 public class DiffUtils {
     31 
     32     public static void scanFileDirectory(String sourceFileUrl, String currentFileUrl, String diffFileUrl) {
     33         // 1. 在diffUrl目录下,创建日期格式的文件夹,用于存放改动的文件
     34         // 1.1 获取当前日期
     35         String nowTime = createCurrentTime();
     36         // 1.2创建日期形式的文件目录
     37         File fileDire = new File(diffFileUrl, nowTime);
     38         fileDire.mkdirs();
     39         String diffFilePath = fileDire.getAbsolutePath();
     40         // 2,遍历出删除的信息,并记录到删除日志文件中
     41         // 2.1创建删除日志文件
     42         String rootPath = fileDire.getAbsolutePath();
     43         File deleteLogFile = new File(rootPath, "delete.log");
     44         try {
     45             deleteLogFile.createNewFile();
     46         } catch (IOException e) {
     47             e.printStackTrace();
     48         }
     49         // 2.2遍历出删除的信息
     50         HashMap<String, Long> sourceUrlMap = getAllFileMap(sourceFileUrl);
     51         HashMap<String, Long> currentUrlMap = getAllFileMap(currentFileUrl);
     52         List<String> deleteFiles = new ArrayList<String>();
     53         String deleteCurrentTime = createCurrentTime();
     54         String diffMessage = "-------- Diff时间:" + deleteCurrentTime + " --------";
     55         try {
     56             FileUtils.writeStringToFile(deleteLogFile, diffMessage + "
    ", "UTF-8", true);
     57         } catch (IOException e1) {
     58             e1.printStackTrace();
     59         }
     60         long start = System.currentTimeMillis();
     61         int delFilecount = 0;
     62         for (Map.Entry<String, Long> sourceEntry : sourceUrlMap.entrySet()) {
     63             // 遍历原版本目录下的文件,如果该文件不在当前版本目录下面,即该文件被删除了
     64             if (!currentUrlMap.containsKey(sourceEntry.getKey())) {
     65                 deleteFiles.add(sourceEntry.getKey());
     66                 delFilecount++;
     67             }
     68         }
     69         long end = System.currentTimeMillis();
     70         // 2.3 删除的信息记录到删除日志文件中
     71         String fileCount = "-------- 共删除文件" + delFilecount + "个--------";
     72         String endContent = "-------- 运行完毕,耗时:" + (end - start) + "ms";
     73         try {
     74             FileUtils.writeLines(deleteLogFile, "UTF-8", deleteFiles, true);
     75             FileUtils.write(deleteLogFile, fileCount + "
    ", "UTF-8", true);
     76             FileUtils.write(deleteLogFile, endContent + "
    ", "UTF-8", true);
     77         } catch (IOException e) {
     78             e.printStackTrace();
     79         }
     80         // 3.将所有新增与更新信息记录到更新日志文件中
     81         // 3.1 创建新增/更新日志文件
     82         File updateAndAddLogFile = new File(rootPath, "updateAndAdd.log");
     83         try {
     84             updateAndAddLogFile.createNewFile();
     85         } catch (IOException e) {
     86             e.printStackTrace();
     87         }
     88         // 3.2遍历新增与更新记录,并存入到集合中
     89         List<String> addFiles = new ArrayList<String>();
     90         List<String> updateFiles = new ArrayList<String>();
     91         /**
     92          * addOrUpdateFileUrls的key-value分别为currentFileUrl文件的全路径名、
     93          * diffFileUrl文件的全路径名 通过文件的完全路径可以获得文件对象,用于后面的文件复制操作
     94          */
     95         Map<String, String> addOrUpdateFileUrls = new HashMap<String, String>();
     96         int addCount = 0;
     97         int updateCount = 0;
     98         long fileAddOrUpdatestart = System.currentTimeMillis();
     99         for (Map.Entry<String, Long> currentUrlMapEntry : currentUrlMap.entrySet()) {
    100             String currentUrlSuffix = currentUrlMapEntry.getKey();
    101             // 如果元素存在原来的目录下,并且crc相同,就是更新操作
    102             if (sourceUrlMap.containsKey(currentUrlMapEntry.getKey())) {
    103                 try {
    104                     long sourceUrlCrc = sourceUrlMap.get(currentUrlMapEntry.getKey());
    105                     long currentUrlCrc = currentUrlMapEntry.getValue();
    106                     if (currentUrlCrc != sourceUrlCrc) {
    107                         updateCount++;
    108                         updateFiles.add(currentUrlSuffix);
    109                         addOrUpdateFileUrls.put(currentFileUrl + currentUrlSuffix, diffFilePath + currentUrlSuffix);
    110                     }
    111                 } catch (Exception e) {
    112                     e.printStackTrace();
    113                 }
    114 
    115             } else {// 如果元素不存在A目录下,就是新增的元素
    116                 addCount++;
    117                 addFiles.add(currentUrlSuffix);
    118                 addOrUpdateFileUrls.put(currentFileUrl + currentUrlSuffix, diffFilePath + currentUrlSuffix);
    119             }
    120         }
    121         long fileAddOrUpdateend = System.currentTimeMillis();
    122         String fileAddOrUpdate = "-------- 运行完毕,耗时:" + (fileAddOrUpdateend - fileAddOrUpdatestart) + "ms";
    123         // 3.3写入日志文件
    124         String addAndUpdateCurrentTime = createCurrentTime();
    125         String addAndUpdateDiffMessage = "-------- Diff时间:" + addAndUpdateCurrentTime + " --------";
    126         String updateCountMessage = "-------- 共更新文件" + updateCount + "个 -------";
    127         String addCountMessage = "-------- 共新增文件" + addCount + "个 -------";
    128         try {
    129             FileUtils.writeStringToFile(updateAndAddLogFile, addAndUpdateDiffMessage + "
    ", "UTF-8", true);
    130             FileUtils.writeStringToFile(updateAndAddLogFile, updateCountMessage + "
    ", "UTF-8", true);
    131             FileUtils.writeLines(updateAndAddLogFile, "UTF-8", updateFiles, true);
    132             FileUtils.writeStringToFile(updateAndAddLogFile, addCountMessage + "
    ", "UTF-8", true);
    133             FileUtils.writeLines(updateAndAddLogFile, "UTF-8", addFiles, true);
    134             FileUtils.writeStringToFile(updateAndAddLogFile, fileAddOrUpdate + "
    ", "UTF-8", true);
    135         } catch (IOException e) {
    136             e.printStackTrace();
    137         }
    138 
    139         // 4.将有新增/修改的文件放入第三个目录中
    140         filesCopy(addOrUpdateFileUrls);
    141     }
    142     
    143     /**
    144      * 循环遍历Map 将路径key获得的文件 复制到value全路径下
    145      */
    146     private static boolean  filesCopy(Map<String, String> addOrUpdateFileUrls){
    147         for (Map.Entry<String, String> addOrUpdateEntry : addOrUpdateFileUrls.entrySet()) {
    148             String filePath = addOrUpdateEntry.getValue();
    149             File diffFile = new File(addOrUpdateEntry.getValue());
    150             String fileDirs = filePath.replace(diffFile.getName(), "");
    151             File creFileDir = new File(fileDirs);
    152             creFileDir.mkdirs();
    153             FileChannel inputChannel = null;
    154             FileChannel outputChannel = null;
    155             FileInputStream fileInputStream = null;
    156             FileOutputStream fileOutputStream = null;
    157             try {
    158                 fileInputStream = new FileInputStream(new File(addOrUpdateEntry.getKey()));
    159                 inputChannel = fileInputStream.getChannel();
    160                 fileOutputStream = new FileOutputStream(diffFile);
    161                 outputChannel = fileOutputStream.getChannel();
    162                 outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
    163             } catch (Exception e) {
    164                 e.printStackTrace();
    165                 return false;
    166             } finally {
    167                 try {
    168                     fileInputStream.close();
    169                 } catch (IOException e) {
    170                     e.printStackTrace();
    171                 }
    172                 try {
    173                     inputChannel.close();
    174                 } catch (IOException e) {
    175                     e.printStackTrace();
    176                 }
    177                 try {
    178                     fileOutputStream.close();
    179                 } catch (IOException e) {
    180                     e.printStackTrace();
    181                 }
    182                 try {
    183                     outputChannel.close();
    184                 } catch (IOException e) {
    185                     e.printStackTrace();
    186                 }
    187             }
    188         }
    189         return true;
    190     }
    191     /**
    192      * 获取yyyy年MM月dd日HH点mm分ss秒格式的当前时间
    193      * 
    194      * @return
    195      */
    196     private static String createCurrentTime() {
    197         Date now = new Date();
    198         SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH点mm分ss秒");
    199         String nowTime = dateFormat.format(now);
    200         return nowTime;
    201     }
    202 
    203     /**
    204      * 将获取到的文件存到map中
    205      * 
    206      * @param path
    207      * @return
    208      */
    209     private static HashMap<String, Long> getAllFileMap(String DirectoryUrl) {
    210 
    211         List<File> allFileList = new ArrayList<File>();
    212         HashMap<String, Long> resMap = new HashMap<String, Long>();
    213 
    214         allFileList = getAllFile(new File(DirectoryUrl), allFileList);
    215         for (File file : allFileList) {
    216             resMap.put(file.getAbsolutePath().replace(DirectoryUrl, ""), getFileCRC(file));
    217         }
    218         return resMap;
    219     }
    220 
    221     /**
    222      * 递归遍历所有文件
    223      * 
    224      * @param file
    225      * @param allFileList
    226      * @return
    227      */
    228     private static List<File> getAllFile(File file, List<File> allFileList) {
    229         if (file.exists()) {
    230             if (file.isDirectory()) {
    231                 File f[] = file.listFiles();
    232                 for (File tempFile : f) {
    233                     getAllFile(tempFile, allFileList);
    234                 }
    235             } else {
    236                 allFileList.add(file);
    237             }
    238         }
    239         return allFileList;
    240     }
    241 
    242     /**
    243      * 获取文件的CRC
    244      * 
    245      * @param file
    246      * @return
    247      * @throws IOException
    248      */
    249     private static long getFileCRC(File file) {
    250         BufferedInputStream bsrc = null;
    251         CRC32 crc = new CRC32();
    252         try {
    253             bsrc = new BufferedInputStream(new FileInputStream(file));
    254             byte[] bytes = new byte[1024];
    255             int i;
    256             while ((i = bsrc.read(bytes)) != -1) {
    257                 crc.update(bytes, 0, i);
    258             }
    259         } catch (Exception e) {
    260 
    261         } finally {
    262             if (bsrc != null) {
    263                 try {
    264                     bsrc.close();
    265                 } catch (IOException e) {
    266                     e.printStackTrace();
    267                 }
    268             }
    269         }
    270         return crc.getValue();
    271     }
    272 }
     1 package comcollection.test;
     2 
     3 import org.junit.Test;
     4 
     5 /**
     6  * @author MJC
     7  *2018年4月25日
     8  * 上午8:55:26
     9  */
    10 public class DiffUtilsTest{
    11 
    12     private static final String oldUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\A";
    13     private static final String newUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\B";
    14     private static final String diffUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\change";
    15     
    16     @Test
    17     public void scanFileDirectory(){
    18         DiffUtils.scanFileDirectory(oldUrl, newUrl, diffUrl);
    19     }
    20 }
    纸上学来终觉浅,觉知此事需躬行
  • 相关阅读:
    WorkFlow入门Step.5—Adding Procedural ElementsForWF4.0(后续)
    WorkFlow设计篇Step.5—用户自定义工作流活动WF4.0
    WorkFlow入门Step.8—Flow Switch的用法
    WorkFlow入门Step.6—Building a Console Application ForWF4.0
    WorkFlow设计篇Step.3—异常处理WF4.0
    WorkFlow设计篇Step.4—异常处理(续)WF4.0
    WorkFlow入门Step.7—Creating a FlowChart WorkFlowForWF4.0
    WorkFlow设计篇Step.2—传参的用法订单金额的处理(续)WF4.0
    近来很忙,很少更新了,发个贴顶一下
    [11.17]本站开通一周年纪念
  • 原文地址:https://www.cnblogs.com/dreamHighMjc/p/8947468.html
Copyright © 2020-2023  润新知