码迷,mamicode.com
首页 > 其他好文 > 详细

Tools/文件同步助手

时间:2020-07-17 13:35:31      阅读:62      评论:0      收藏:0      [点我收藏+]

标签:for   scan   启动器   copy   node   ash   write   test   else   

文件同步助手(本地)

文件

  • sync.js
const fs=require(‘fs‘);
const crypto=require(‘crypto‘);

let config,to_config,from_config;

function test_ignore(path){
    if(config.ignore){
        for(let reg of config.ignore){
            if(reg.test(path)){
                return true;
            }
        }
    }
    return false;
}

function get_keyword(path){
    if(!config.type){
        return 0;
    }
    return new Promise((resolve)=>{
        let file=fs.createReadStream(path);
        let hash=crypto.createHash(config.type);
        file.on(‘data‘,(data)=>{
            hash.update(data);
        });
        file.on(‘end‘,()=>{
            resolve(hash.digest(‘hex‘));
        });
    });
}

async function scan_path(base,path=‘‘){
    process.title=`${base}${path}`;
    let res={
        d:{},
        f:{}
    };
    let now_list=fs.readdirSync(`${base}${path}`);
    for(let now_path of now_list){
        if(test_ignore(`${base}${path}/${now_path}`)){
            continue;
        }
        if(fs.statSync(`${base}${path}/${now_path}`).isDirectory()){
            res.d[now_path]=await scan_path(base,`${path}/${now_path}`);
        }
        else{
            res.f[now_path]=await get_keyword(`${base}${path}/${now_path}`);
        }
    }
    return res;
}

function remove_dir(base,path,res){
    for(let dir in res.d){
        remove_dir(base,`${path}/${dir}`,res.d[dir]);
        fs.rmdirSync(`${base}${path}/${dir}`);
    }
    for(let file in res.f){
        fs.unlinkSync(`${base}${path}/${file}`);
    }
}

async function compare_path(from,to,path=‘‘){
    //-- compare to
    for(let dir in to.d){
        if(from.d[dir]){
            compare_path(from.d[dir],to.d[dir],`${path}/${dir}`);
        }
        else{
            remove_dir(config.to,`${path}/${dir}`,to.d[dir]);
            console.log(`-td`,`${config.to}${path}/${dir}`);
            fs.rmdirSync(`${config.to}${path}/${dir}`);
            delete to.d[dir];
        }
    }
    for(let file in to.f){
        if(!from.f[file]){
            console.log(`-tf`,`${config.to}${path}/${file}`);
            fs.unlinkSync(`${config.to}${path}/${file}`);
            delete to.f[file];
        }
    }
    //-- compare from
    for(let dir in from.d){
        if(!to.d[dir]){
            console.log(`+fd`,`${config.to}${path}/${dir}`);
            fs.mkdirSync(`${config.to}${path}/${dir}`);
            to.d[dir]={
                d:{},
                f:{}
            };
        }
        compare_path(from.d[dir],to.d[dir],`${path}/${dir}`);
    }
    for(let file in from.f){
        if(to.f[file]&&to.f[file]!=from.f[file]){
            console.log(`-ff`,`${config.to}${path}/${file}`);
            fs.unlinkSync(`${config.to}${path}/${file}`);
            delete to.f[file];
        }
        if(!to.f[file]){
            console.log(`+ff`,`${config.to}${path}/${file}`);
            fs.copyFileSync(`${config.from}${path}/${file}`,`${config.to}${path}/${file}`);
            to.f[file]=from.f[file];
        }
    }
}

async function __main(){
    const config_path=process.argv[2].replace(/\\/g,‘/‘);

    if(!fs.existsSync(config_path)){
        throw new Error(`no such config file`);
    }

    config=JSON.parse(fs.readFileSync(config_path));

    const to_config_path=`${config.to}/sync_config.json`;

    if(config.ignore){
        for(let i=0;i<config.ignore.length;i++){
            config.ignore[i]=new RegExp(...config.ignore[i]);
        }
    }

    from_config=await scan_path(config.from);
    if(fs.existsSync(to_config_path)){
        to_config=JSON.parse(fs.readFileSync(to_config_path));
    }
    else{
        to_config=await scan_path(config.to);
    }

    compare_path(from_config,to_config);

    fs.writeFileSync(to_config_path,JSON.stringify(to_config));
}
__main();
  • sync.bat //启动器
node sync.js %*
pause
  • config.json //例子
{
    "from":"C:/Users/fhs/Documents/tools-fl",
    "to":"R:/dev",
    "ignore":[
        [".vscode"],
        ["node_modules"]
    ],
    "type":"md5"
}

config.json

from //要备份的文件夹(必须)
to //要备份的目标目录(必须)
ignore //匹配忽略的文件夹
[
    ["www\\.\d+","ig"]
]
type //hash模式 不填写则直接比较文件

Tools/文件同步助手

标签:for   scan   启动器   copy   node   ash   write   test   else   

原文地址:https://www.cnblogs.com/FireHumansSkeleton/p/13328465.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!