node 实现文件夹自动同步

时间:2024-02-18 11:26:52

主要功能,

  监视一个文件夹,当有文件新增,修改,删除时自动同步到指定的文件夹

需要安装的模块

  npm install chokidar
  npm install iconv-lite

说明node没有专门的copy文件的方法,这用适合小文件copy的方法,因为是直接copy,读取和写入都是直接二进制。({encoding:\'binary\'})

 

// process.exit();

var fs,path,chokidar,dir1,tra1,tra2,pDir,exec,iconv,allRun=0;
fs = require(\'fs\');  
path= require("path");
chokidar = require(\'chokidar\');
iconv = require(\'iconv-lite\');
// exec = require(\'child_process\').exec;

// youyoue 本地间的文件同步
dir1=\'G:/webS/www/youyue/web\'.replace(/\//g,path.sep);
tra2=\'G:/webS/www/youyuet/web\'.replace(/\//g,path.sep);


watcherBl(dir1,dir1,tra2);
//    npm install iconv-lite
function watcherBl(dir1,tra1,tra2,noSyn){
    var watcher;
    mkdirsSync(tra2, \'0777\');
    allRun++;
    watcher = chokidar.watch(dir1, {ignored: /[\/\\]\./, persistent: true, });
    watcher.on(\'ready\',function(){
        allRun--;
        if(allRun===0)console.log( "run.." );
        watcher
        .on(\'add\', function(pathD) {

            var path_n=pathD.replace(tra1,tra2);
            mkdirsSync(path.dirname(path_n), \'0777\');
            copy(pathD,path_n);
            fs.stat(pathD, function(err1, stats) {
                if (err1){  
                    console.log(\'stat error\');
                    return false; 
                }
                fs.utimes(path_n,stats.mtime,stats.mtime,function(err){
                    if(err)console.log(\'time error\'+err);
                });
            });
             
            // console.log( \'add\'+\'_\'+ path);
        })
        .on(\'addDir\', function(path) { 
            var path_n=path.replace(tra1,tra2);
            mkdirsSync(path_n, \'0777\');
            
            // console.log( \'addDir\'+\'_\'+ path);
        })
        .on(\'change\', function(path) {
            var path_n=path.replace(tra1,tra2);

            setTimeout(function () {
                copy(path,path_n);
                fs.stat(path, function(err1, stats) {
                    if (err1){  
                        console.log(\'stat error\');
                        return false; 
                    }
                    fs.utimes(path_n,stats.mtime,stats.mtime,function(err){
                        if(err)console.log(\'time error\'+err);
                    });
                });
            }, 500);
                 
            // console.log( \'change\'+\'_\'+ path );  
        })
        .on(\'unlink\', function(path) { 
            var path_n,JsonObj;
            if(noSyn){
                path_n=path.replace(tra1,\'\');
                if(fs.existsSync(pDir+\'/file_list.json\')){
                    JsonObj=JSON.parse(fs.readFileSync(pDir+\'/file_list.json\'));
                }else{
                    JsonObj={list:[]};
                }
                JsonObj.list.push(path_n);
                fs.writeFileSync(pDir+\'/file_list.json\',JSON.stringify(JsonObj));

            }else{
                path_n=path.replace(tra1,tra2);
                fs.unlink(path_n,function(err){if(err)console.log(\'time error\'+err); });
            }
            
            // console.log( \'unlink\'+\'_\'+ path );
        })
        .on(\'unlinkDir\', function(path) { 
            var path_n,JsonObj;
            if(noSyn){
                path_n=path.replace(tra1,\'\');
                if(fs.existsSync(pDir+\'/dir_list.json\')){
                    JsonObj=JSON.parse(fs.readFileSync(pDir+\'/dir_list.json\'));
                }else{
                    JsonObj={list:[]};
                }
                JsonObj.list.push(path_n);
                fs.writeFileSync(pDir+\'/dir_list.json\',JSON.stringify(JsonObj));

            }else{
                path_n=path.replace(tra1,tra2);
                deleteFolder(path_n);
            }
            
            // console.log( \'unlinkDir\'+\'_\'+ path );
        })
        .on(\'error\', function(error) { console.log(\'Error happened\', error); });

    });
}


/**
 * 创建文件夹 _同步操作
 * @param  {[string]} dirpath  [路径]
 * @param  {[string]}   mode   [权限:\'0777\']
 * @param  {Function} callback [description]
 * @return {[type]}            [description]
 */
function mkdirsSync(dirpath, mode, callback) {
    callback = callback || function(){};
    if( fs.existsSync(dirpath) ){       
        callback(dirpath);
    }else{  
        mkdirsSync(path.dirname(dirpath), mode, function(){
            fs.mkdirSync(dirpath, mode);
            callback(dirpath);
        });
    }
}
/**
 * 复制小文件 _同步操作
 * @param  {[path]} src [原文件路径]
 * @param  {[path]} dst [要复制到的文件路径]
 * @return {[type]}     [description]
 */
function copy(src, dst ) {

    var con;
    try {
        con=fs.readFileSync(src,{encoding:\'binary\'}); 
        fs.writeFileSync(dst, con,{encoding:\'binary\'});
    } catch (ex) {
        console.log( src +\'_\' + dst+\'_\'+ex );
    }

    // con=iconv.decode( fs.readFileSync(src), \'utf8\'); 
    // fs.writeFileSync(dst, iconv.encode(con, \'gbk\'),{encoding:\'\'}); 
         
    // var str=\'copy "\'+src+\'" "\'+dst+\'"\';
    // exec(str,function(error,stdout,stderr){if(error!==null){console.log(\'exec error: \' + error); } });
    
    // try {
    //     fs.writeFileSync(dst, fs.readFileSync(src));
    // } catch (ex) {
    //     console.log( src +\'_\' + dst );
    // }
}

/**
 * 删除文件夹 _同步操作
 * @param  {[type]} path [description]
 * @return {[type]}      [description]
 */
function deleteFolder(path) {
    var files = [];
    if( fs.existsSync(path) ) {
        files = fs.readdirSync(path);
        files.forEach(function(file,index){
            var curPath = path + "/" + file;
            if(fs.statSync(curPath).isDirectory()) { // recurse
                deleteFolder(curPath);
            } else { // delete file
                fs.unlinkSync(curPath);
            }
        });
        fs.rmdirSync(path);
    }
}