没心情优化代码了,就先这样吧
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