编写一个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 + "\n", "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 + "\n", "UTF-8", true);
 76             FileUtils.write(deleteLogFile, endContent + "\n", "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 + "\n", "UTF-8", true);
130             FileUtils.writeStringToFile(updateAndAddLogFile, updateCountMessage + "\n", "UTF-8", true);
131             FileUtils.writeLines(updateAndAddLogFile, "UTF-8", updateFiles, true);
132             FileUtils.writeStringToFile(updateAndAddLogFile, addCountMessage + "\n", "UTF-8", true);
133             FileUtils.writeLines(updateAndAddLogFile, "UTF-8", addFiles, true);
134             FileUtils.writeStringToFile(updateAndAddLogFile, fileAddOrUpdate + "\n", "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 }

原文地址:https://www.cnblogs.com/dreamHighMjc/p/8947468.html

时间: 2024-10-10 14:32:27

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

一个diff工具,用于判断两个目录下所有的改动(比较新旧版本文件夹)

需求: 编写一个diff工具,用于判断两个目录下所有的改动 详细介绍: 有A和B两个目录,目录所在位置及层级均不确定 需要以B为基准找出两个目录中所有有改动的文件(文件或内容增加.修改.删除),将有改动的文件放入第三个目录中,层级结构与原目录相同 将所有新增与更新信息记录到更新日志文件中 将删除信息单独记录到删除日志文件中 每次执行diff工具需要生成一个新的以日期命名的目录存放文件 使用场景: 本工具用于软件版本升级时找出两个版本间所有修改过的文件,便于增量替换. 提示:    使用CRC判断

编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成

编写一个函数isMerge,判断一个字符串str是否可以由其他两个字符串part1和part2“组合”而成.“组合 ”的规则如下: 1). str中的每个字母要么来自于part1,要么来自于part2; 2). part1和part2中字母的顺序与str中字母的顺序相同. 例如: "codewars"由"cdw"和"oears"组合而成: s: c o d e w a r s = codewars part1: c d w = cdw part2

编写一个宏,实现判断数组a元素的个数

#include <iostream> using namespace std; #define TestArrayLengthA(A) sizeof(A)/sizeof(*A) #define TestArrayLengthB(B) sizeof(B)/sizeof(B[0]) //这样测出的是数组可以放多少个元素,比如Array[100],他返回的是100, //不论你初始化还是没有初始化 int TestArrayLength(T *a) { int count = 0; T *p =

编写一个程序,用户输入两个数,求出其加减乘除,并用消息框显示计算结果

编写一个程序,用户输入两个数,求出其加减乘除,并用消息框显示计算结果 import javax.swing.JOptionPane; public class Test{ public static void main(String[] args) { int n1=Integer.parseInt(JOptionPane.showInputDialog("Input number 1: ")); int n2=Integer.parseInt(JOptionPane.showInpu

习题4 编写一个方法method(),判断一个数能否同时被3和5整除

编写一个方法method(),判断一个数能否同时被3和5整除 首先编写一个方法method(),由于是判断,所以返回的数据类型应是波尔型,并且向主方法传一个整数类型的参数X public class Zhawo11 { } public static boolean method(int x){ } } 接下来在子方法里判断,如果能同同时被3和5整除,就返回true,否则返回false public class Zhawo11 { public static void main(String a

用C++编写一个随机产生多个两位数四则运算式子的简单程序

一 设计思想: 1.首先可以想到一个四则运算式子的组成:两个运算数和一个运算符: 2.两个运算数的随机由调用随机函数产生,其中可以设定运算数的范围: 3.一个运算符的随机产生可以分为加减乘除四种情况,分别通过产生四个随机数来决定哪种运算符: 4.最后两者结合起来完成随机式子的产生: 二 程序代码: #include "stdafx.h" #include "stdlib.h" //调用其中随机函数 #include "iostream.h" #i

python练习:编写一个函数isIn,接受两个字符串作为参数,如果一个字符串是另一个字符串的一部分,返回True,否则返回False。

重难点:定义函数的方法.使用str类型的find()函数,可以查找多个字符.第二种方法为把字符串转化为字符队列,然后遍历寻找,但是只可以寻找一个字符. 1 print("----------------------------") 2 def isIn(x,y):#def定义函数保留字 3 v=y.find(x) 4 if v>=0: 5 return True; 6 else: 7 return False; 8 print(isIn('sxc','azdsxcv'))#输出函

编写一个程序,用户输入两个数,求其加减乘除,并用消息框显示计算结果。

代码: //an complex program import javax.swing.JOptionPane;//import class JOptionPane public class Complex { public static void main(String[] args) { // TODO 自动生成的方法存根 String firstNumber,     //first string entered by user secondNumber;    //second stri

编写一个输入某年月日,判断这一天是这一年的第几天的程序

#include<stdio.h> int main() { int year,month,day,sum,leap; printf("Please enter year,month,day (just like:2009,9,9)\n"); scanf("%d,%d,%d",&year,&month,&day); switch(month) {case 1 : sum=0; break; case 2 : sum=31; bre