编写一个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 }

猜你喜欢

转载自www.cnblogs.com/dreamHighMjc/p/8947468.html
今日推荐