zoukankan      html  css  js  c++  java
  • 编写一个diff工具,用于判断两个目录下所有的改动--2.0版本

    package comcollection.test;
    
    import java.io.BufferedInputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.nio.channels.FileChannel;
    import java.text.SimpleDateFormat;
    import java.util.ArrayList;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.zip.CRC32;
    
    import org.apache.commons.io.FileUtils;
    
    /**
     * 
     * 1.有A和B两个目录,目录所在位置及层级均不确定
     * 2.需要以B为基准找出两个目录中所有有改动的文件(文件或内容增加、修改、删除),将有改动的文件放入第三个目录中,层级结构与原目录相同
     * 3.将所有新增与更新信息记录到更新日志文件中 
     * 4.将删除信息单独记录到删除日志文件中 
     * 5.每次执行diff工具需要生成一个新的以日期命名的目录存放文件
     */
    
    public class DiffUtils {
    
        public static void scanFileDirectory(String sourceFileUrl, String currentFileUrl, String diffFileUrl) {
            // 1. 在diffUrl目录下,创建日期格式的文件夹,用于存放改动的文件
            // 1.1 获取当前日期
            String nowTime = createCurrentTime();
            // 1.2创建日期形式的文件目录
            File fileDire = new File(diffFileUrl, nowTime);
            fileDire.mkdirs();
            String diffFilePath = fileDire.getAbsolutePath();
            // 2,遍历出删除的信息,并记录到删除日志文件中
            // 2.1创建删除日志文件
            String rootPath = fileDire.getAbsolutePath();
            File deleteLogFile = new File(rootPath, "delete.log");
            try {
                deleteLogFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 2.2遍历出删除的信息
            HashMap<String, Long> sourceUrlMap = getAllFileMap(sourceFileUrl);
            HashMap<String, Long> currentUrlMap = getAllFileMap(currentFileUrl);
            List<String> deleteFiles = new ArrayList<String>();
            String deleteCurrentTime = createCurrentTime();
            String diffMessage = "-------- Diff时间:" + deleteCurrentTime + " --------";
            try {
                FileUtils.writeStringToFile(deleteLogFile, diffMessage + "
    ", "UTF-8", true);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            long start = System.currentTimeMillis();
            int delFilecount = 0;
            for (Map.Entry<String, Long> sourceEntry : sourceUrlMap.entrySet()) {
                // 遍历原版本目录下的文件,如果该文件不在当前版本目录下面,即该文件被删除了
                if (!currentUrlMap.containsKey(sourceEntry.getKey())) {
                    deleteFiles.add(sourceEntry.getKey());
                    delFilecount++;
                }
            }
            long end = System.currentTimeMillis();
            // 2.3 删除的信息记录到删除日志文件中
            String fileCount = "-------- 共删除文件" + delFilecount + "个--------";
            String endContent = "-------- 运行完毕,耗时:" + (end - start) + "ms";
            try {
                FileUtils.writeLines(deleteLogFile, "UTF-8", deleteFiles, true);
                FileUtils.write(deleteLogFile, fileCount + "
    ", "UTF-8", true);
                FileUtils.write(deleteLogFile, endContent + "
    ", "UTF-8", true);
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 3.将所有新增与更新信息记录到更新日志文件中
            // 3.1 创建新增/更新日志文件
            File updateAndAddLogFile = new File(rootPath, "updateAndAdd.log");
            try {
                updateAndAddLogFile.createNewFile();
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 3.2遍历新增与更新记录,并存入到集合中
            List<String> addFiles = new ArrayList<String>();
            List<String> updateFiles = new ArrayList<String>();
            /**
             * addOrUpdateFileUrls的key-value分别为currentFileUrl文件的全路径名、
             * diffFileUrl文件的全路径名 通过文件的完全路径可以获得文件对象,用于后面的文件复制操作
             */
            Map<String, String> addOrUpdateFileUrls = new HashMap<String, String>();
            int addCount = 0;
            int updateCount = 0;
            long fileAddOrUpdatestart = System.currentTimeMillis();
            for (Map.Entry<String, Long> currentUrlMapEntry : currentUrlMap.entrySet()) {
                String currentUrlSuffix = currentUrlMapEntry.getKey();
                // 如果元素存在原来的目录下,并且crc相同,就是更新操作
                if (sourceUrlMap.containsKey(currentUrlMapEntry.getKey())) {
                    try {
                        long sourceUrlCrc = sourceUrlMap.get(currentUrlMapEntry.getKey());
                        long currentUrlCrc = currentUrlMapEntry.getValue();
                        if (currentUrlCrc != sourceUrlCrc) {
                            updateCount++;
                            updateFiles.add(currentUrlSuffix);
                            addOrUpdateFileUrls.put(currentFileUrl + currentUrlSuffix, diffFilePath + currentUrlSuffix);
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
    
                } else {// 如果元素不存在A目录下,就是新增的元素
                    addCount++;
                    addFiles.add(currentUrlSuffix);
                    addOrUpdateFileUrls.put(currentFileUrl + currentUrlSuffix, diffFilePath + currentUrlSuffix);
                }
            }
            long fileAddOrUpdateend = System.currentTimeMillis();
            String fileAddOrUpdate = "-------- 运行完毕,耗时:" + (fileAddOrUpdateend - fileAddOrUpdatestart) + "ms";
            // 3.3写入日志文件
            String addAndUpdateCurrentTime = createCurrentTime();
            String addAndUpdateDiffMessage = "-------- Diff时间:" + addAndUpdateCurrentTime + " --------";
            String updateCountMessage = "-------- 共更新文件" + updateCount + "个 -------";
            String addCountMessage = "-------- 共新增文件" + addCount + "个 -------";
            try {
                FileUtils.writeStringToFile(updateAndAddLogFile, addAndUpdateDiffMessage + "
    ", "UTF-8", true);
                FileUtils.writeStringToFile(updateAndAddLogFile, updateCountMessage + "
    ", "UTF-8", true);
                FileUtils.writeLines(updateAndAddLogFile, "UTF-8", updateFiles, true);
                FileUtils.writeStringToFile(updateAndAddLogFile, addCountMessage + "
    ", "UTF-8", true);
                FileUtils.writeLines(updateAndAddLogFile, "UTF-8", addFiles, true);
                FileUtils.writeStringToFile(updateAndAddLogFile, fileAddOrUpdate + "
    ", "UTF-8", true);
            } catch (IOException e1) {
                e1.printStackTrace();
            }
    
            // 4.将有新增/修改的文件放入第三个目录中
            for (Map.Entry<String, String> addOrUpdateEntry : addOrUpdateFileUrls.entrySet()) {
                String filePath = addOrUpdateEntry.getValue();
                File diffFile = new File(addOrUpdateEntry.getValue());
                String fileDirs = filePath.replace(diffFile.getName(), "");
                File creFileDir = new File(fileDirs);
                creFileDir.mkdirs();
                FileChannel inputChannel = null;
                FileChannel outputChannel = null;
                FileInputStream fileInputStream = null;
                FileOutputStream fileOutputStream = null;
                try {
                    fileInputStream = new FileInputStream(new File(addOrUpdateEntry.getKey()));
                    inputChannel = fileInputStream.getChannel();
                    fileOutputStream = new FileOutputStream(diffFile);
                    outputChannel = fileOutputStream.getChannel();
                    outputChannel.transferFrom(inputChannel, 0, inputChannel.size());
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    try {
                        fileInputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        inputChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    try {
                        outputChannel.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    
        /**
         * 获取yyyy年MM月dd日HH点mm分ss秒格式的当前时间
         * 
         * @return
         */
        private static String createCurrentTime() {
            Date now = new Date();
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日HH点mm分ss秒");
            String nowTime = dateFormat.format(now);
            return nowTime;
        }
    
        /**
         * 将获取到的文件存到map中
         * 
         * @param path
         * @return
         */
        private static HashMap<String, Long> getAllFileMap(String DirectoryUrl) {
    
            List<File> allFileList = new ArrayList<File>();
            HashMap<String, Long> resMap = new HashMap<String, Long>();
    
            allFileList = getAllFile(new File(DirectoryUrl), allFileList);
            for (File file : allFileList) {
                resMap.put(file.getAbsolutePath().replace(DirectoryUrl, ""), getFileCRC(file));
            }
            return resMap;
        }
    
        /**
         * 递归遍历所有文件
         * 
         * @param file
         * @param allFileList
         * @return
         */
        private static List<File> getAllFile(File file, List<File> allFileList) {
            if (file.exists()) {
                if (file.isDirectory()) {
                    File f[] = file.listFiles();
                    for (File tempFile : f) {
                        getAllFile(tempFile, allFileList);
                    }
                } else {
                    allFileList.add(file);
                }
            }
            return allFileList;
        }
    
        /**
         * 获取文件的CRC
         * 
         * @param file
         * @return
         * @throws IOException
         */
        private static long getFileCRC(File file) {
            BufferedInputStream bsrc = null;
            CRC32 crc = new CRC32();
            try {
                bsrc = new BufferedInputStream(new FileInputStream(file));
                byte[] bytes = new byte[1024];
                int i;
                while ((i = bsrc.read(bytes)) != -1) {
                    crc.update(bytes, 0, i);
                }
            } catch (Exception e) {
    
            } finally {
                if (bsrc != null) {
                    try {
                        bsrc.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return crc.getValue();
        }
    }

    测试代码如下:

    package comcollection.test;
    
    import org.junit.Test;
    
    /**
     * @author MJC
     *2018年4月25日
     * 上午8:55:26
     */
    public class DiffUtilsTest {
    
        private static final String oldUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\A";
        private static final String newUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\B";
        private static final String diffUrl = "C:\Users\jljd\Desktop\diff工具需求说明及示例\diff工具需求说明及示例\change";
        
        @Test
        public void scanFileDirectory(){
            DiffUtils.scanFileDirectory(oldUrl, newUrl, diffUrl);
        }
    }
    纸上学来终觉浅,觉知此事需躬行
  • 相关阅读:
    sap mm_1
    SAP
    tomcat配置
    sap
    数据库范式
    SAP_20140304
    Eclipse 常用设置
    Oracle常用命令1
    Mysql 学习笔记 20140219
    java 宠物商店代码
  • 原文地址:https://www.cnblogs.com/dreamHighMjc/p/8946556.html
Copyright © 2011-2022 走看看