文件差分更新

文件差分更新

项目中需要有一个文件差分更新的功能,本来是想着使用一个版本文件,即先遍历每一个文件,然后生成对应的md5码,然后新文件也采用相同的方法,然后拷贝md5码不一致或者新出现的文件,但是发现不是很好实践,不如去遍历每一个文件,然后对比两个文件之间存在差异。但是使用直接遍历,性能比较差,我们可以使用一个相对路径,把新文件和旧文件,然后之间每一个文件的相对路径即可,这样时间复杂度就是O(n)了。

代码

这里我们使用commons-io的文件工具类,主要是使用它的一个遍历和拷贝。

        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.5</version>
        </dependency>

工具类代码如下:

package cn.stopyc.util;

import org.apache.commons.io.DirectoryWalker;
import org.apache.commons.io.filefilter.FileFilterUtils;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;

/**
 * @program: Utils
 * @description: 文件工具类
 * @author: stop.yc
 * @create: 2023-02-28 00:13
 **/
public class MyFileUtils {

    static class DirectoryDiff extends DirectoryWalker<File> {

        private final File baseDirectory;
        private final File compareDirectory;

        public DirectoryDiff(File baseDirectory, File compareDirectory) {
            super(FileFilterUtils.trueFileFilter(), -1);
            this.baseDirectory = baseDirectory;
            this.compareDirectory = compareDirectory;
        }

        /**
         * DirectoryDiff调用walk遍历文件时处理文件夹的逻辑,没有该文件直接添加
         * @param directory :文件夹
         * @param depth :目标深度
         * @param results :有差异的结果集
         * @return :是否成功
         * @throws IOException :io异常
         */
        @Override
        protected boolean handleDirectory(File directory, int depth, Collection<File> results) throws IOException {
            // 获取相对路径
            String relativePath = getRelativePath(baseDirectory, directory);
            // 计算比较目录下的路径
            File compareDir = new File(compareDirectory, relativePath);
            if (!compareDir.exists()) {
                // 目录不存在时直接添加到结果集中
                results.add(directory);
            }
            return true;
        }

        /**
         * DirectoryDiff调用walk遍历文件时处理文件的逻辑,没有文件或者文件内容不一致时添加
         * @param file :文件
         * @param depth : 深度
         * @param results :结果集
         * @throws IOException :ioException
         */
        @Override
        protected void handleFile(File file, int depth, Collection<File> results) throws IOException {
            // 获取相对路径
            String relativePath = getRelativePath(baseDirectory, file);
            // 计算比较目录下的路径
            File compareFile = new File(compareDirectory, relativePath);
            if (!compareFile.exists() || !org.apache.commons.io.FileUtils.contentEquals(file, compareFile)) {
            //if (!compareFile.exists() || !org.apache.commons.io.FileUtils.isFileNewer(file, compareFile)) {
                // 文件不存在或者内容不一致时添加到结果集中
                results.add(file);
            }
        }

        /**
         * 获取差异文件,并对其进行复制到目标文件夹
         * @param baseDirectory :基准文件(最新的文件,与旧版本存在差异)
         * @param compareDirectory :对比的文件(需要被更新的文件, 获取新文件的差异内容)
         */
        protected static void diffDirectoryIn(File baseDirectory, File compareDirectory) {
            Collection<File> diffFiles = new ArrayList<>();
            DirectoryDiff diff = new DirectoryDiff(baseDirectory, compareDirectory);
            try {
                //遍历,内部调用handleFile和handleDirectory,把差异文件进行添加
                diff.walk(baseDirectory, diffFiles);
            } catch (IOException e) {
                e.printStackTrace();
                throw new RuntimeException("IOException");
            }
            //存在差异的文件进行复制.
            diffFiles.stream()
                    .filter(File::isFile)
                    .forEach(diffFile -> {
                        String relativePath = getRelativePath(baseDirectory, diffFile);
                        File baseFile = new File(compareDirectory, relativePath);
                        if (!baseFile.getParentFile().exists()) {
                            baseFile.getParentFile().mkdirs();
                        }
                        if (diffFile.isDirectory()) {
                            try {
                                org.apache.commons.io.FileUtils.copyDirectory(diffFile, baseFile);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        } else {
                            try {
                                org.apache.commons.io.FileUtils.copyFile(diffFile, baseFile);
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    });
        }

        /**
         * 获取相对路径
         * @param base :基准文件
         * @param file :目标文件
         * @return :相对路径
         */
        private static String getRelativePath(File base, File file) {
            return base.toURI().relativize(file.toURI()).getPath();
        }
    }

    /**
     * 文件差分更新
     * @param baseDirectoryPath :新文件路径
     * @param compareDirectoryPath :旧文件路径
     */
    public static void diffDirectory(String baseDirectoryPath, String compareDirectoryPath) {
        File baseDirectory = new File(baseDirectoryPath);
        File compareDirectory = new File(compareDirectoryPath);
        DirectoryDiff.diffDirectoryIn(baseDirectory, compareDirectory);
    }

    /**
     * 文件差分更新
     * @param baseDirectory :新文件
     * @param compareDirectory :旧文件
     */
    public static void diffDirectory(File baseDirectory, File compareDirectory) {
        DirectoryDiff.diffDirectoryIn(baseDirectory, compareDirectory);
    }

    public static void main(String[] args) throws IOException {
        File baseDirectory = new File("F:\\QGAssessment2023Spring\\");
        File compareDirectory = new File("F:\\QGAssessment2023Spring - 副本\\");
        MyFileUtils.diffDirectory("F:\\QGAssessment2023Spring\\", "F:\\QGAssessment2023Spring - 副本\\");
        MyFileUtils.diffDirectory(baseDirectory, compareDirectory);
    }
}
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇