zoukankan      html  css  js  c++  java
  • windows 文件watch nodejs

    本篇博客,主要是记录下最近一直纠结的gulp.watch方法,在工作中我们肯定都遇到过,新添加的文件没办法自动触发watch,下面我们就来看有什么办法处理

    1.首先我们肯定是先百度一下

       百度推荐的是gulp-watch插件,这个插件其实是基于上片博客的提到的node模块chokidar。可以监控文件的增删改查,重命名的会发送一个添加和一个删除

       但是用这个模块,在关闭控制台的时候,会有一段时间的无响应时间,感觉重视怪怪的

    2.本人平时在windows下面,还会熟悉写arrdio的脚本语言,这个语言对文件的监控,也有相关的模块,其实相对使用的是Kernel32.dll里面的Windows api

        ReadDirectoryChangesW  MSDN直通车 

        但是arrdio exe程序怎么和nodejs程序通信的,以前也有相关的尝试,

        a.通过进程的输入,输出设备相关,打印信息。后台发现该方案只能是子进程返回给主进程信息就放弃了。

        b.基于http,主要感觉要占用端口,而且http也是响应式的,相关的交互也有点麻烦

        c.基于TCP,tcp属于长连接,server和client 可以相互通信,这又是好一顿折腾(TCP服务是node还是arrdio创建,后来是考虑arrdio创建,主要是想在mynote项目里面,也借助tcp服务,进行让node在Windows使用sqlite数据库【主要是网上没有找到相关windows下编译好的sqlite模块,自己又没有相关的环境和知识】)

    总结下相关的对比

      gulp.watch chokidar aau.watch
    初始化   ready事件之前会有文件的add事件  
    文件添加 无反应 add 添加文件
    删除文件

    运行前存在的 deleted

    运行后添加的 无反应

    unlink 移除文件
    重命名文件

    运行前存在的 deleted

    运行后添加的 无反应

    被重名文件  unlink

    重命名后文件 add

    被重命名文件  重命名:原文件

    重命名后文件  重命名:新文件名

    重命名后文件  文件被修改

    修改文件

    运行前存在的 changed

    运行后添加的 无反应

    change

    文件被修改

    aau.watch采用的是TCP消息通信,但是由于文件重命名,消息比较频繁,短时间内3条信息传递,导致node的tcp客户端,存在调包,或者少响应data时间的现象。

    相关的我也写了arrdio的tcp客户端的响应处理,只是获取的消息会一次性获取,没有掉包的情况。

    不知道其中是什么原因导致的。

    下面贴下相关的代码

    node watch.js代码

    var net = require('net');
    var gulp = require('gulp');
    var chokidar = require('chokidar');
    
    var HOST = '127.0.0.1';
    var PORT = 7070;
    
    var actionTab = ["", "添加文件", "移除文件", "文件被修改", "重命名:原文件名", "重命名:新文件名"];
    var client = new net.Socket();
    client.connect(PORT, HOST, function() {
        client.write('{action: "dirWatch", url:"D:/snailshop/wgu/"}');
    });
    client.on('data', function(data) {
        var tab = data.toString().split(',');
        console.log('[aau.watch]', tab[1], actionTab[tab[0]], +new Date)
    });
    client.on('close', function() {
        console.log('Connection closed');
    });
    /*
    net.createServer(function(sock) {
        console.log('CONNECTED: ' + sock.remoteAddress + ':' + sock.remotePort);
        sock.on('data', function(data) {
            console.log('DATA ' + sock.remoteAddress + ': ' + data);
            sock.write('You said "' + data + '"');
        });
        sock.on('close', function(data) {
            console.log('CLOSED: ' + sock.remoteAddress + ' ' + sock.remotePort);
        });
    }).listen(PORT, HOST);*/
    gulp.watch(['./wgu/**/*'], event => {
        console.log('[gulp.watch]', event.path, event.type, +new Date)
    });
    var watcher = chokidar.watch(['./wgu/**/*'], {
        ignored: /[/\]./,
        persistent: true
    });
    'add,change,unlink,addDir,unlinkDir,ready'.split(',').forEach(item => {
        watcher.on(item, path => {
            console.log('[chokidar]', path, item, +new Date)
        })
    })

    arrdio tcp server,相关的都有封装,只需要写比较少的代码,唯一可惜的是官网的文档比较少,需要花一定的时间自己了解怎么写法

    import console;
    import wsock.tcp.server;
    import wsock.tcp.client;
    import thread.command;
    
    var tcpTab = {};
    var listener = ..thread.command();//线程命令,对线程抛出的消息进行处理
    listener.onFileChange = function (msg) {
        for (i = 1; #tcpTab; 1) {
            tcpTab[i].write(msg)
        }
    };
    var tcpServer, errMsg = wsock.tcp.server("127.0.0.1", 7070);
    if(!tcpServer) {
        console.log( errMsg )
        console.pause();
    } else {
        tcpServer.forever(function(acceptSocket){
            table.push(tcpTab, wsock.tcp.client(, acceptSocket)) //保存客户端socket
            ..thread.invoke(function(acceptSocket, hwndListener){ //启动单独线程,响应每一个客户端的请求
                import wsock.tcp.client;
                import web.json;
                import fsys.dirWatcher;
                import console;    
                import thread.command; 
                
                var tcpClient = wsock.tcp.client(, acceptSocket);
                do{
                    var cstr = tcpClient.recv();
                    if (cstr) {
                        var obj = web.json.parse(cstr);
                        console.dump(obj)
                        if (obj && type(obj) == 'table' && obj.action == 'dirWatch') {
                            var watcher = fsys.dirWatcher(obj.url);
                            for( filename,action,actionText,item in watcher.eachChanges(flags,subTree) ){
                                //console.log(1, string.join({action;filename;}, ","))
                                //tcpClient.write(string.join({action;filename;}, ","))
                                thread.command.post(hwndListener, "onFileChange", string.join({action;filename;}, ","));  //线程命令处理
                            } 
                        }
                    }
                } while(1)
            }, acceptSocket, listener.hwnd);
        })
    }
          

    arrdio的tcp客户端(用于测试重命名消息的处理能力)

    import console;
    import wsock.tcp.client;
    import fsys.dirWatcher;
    
    var tcpc = wsock.tcp.client();
    tcpc.connect("127.0.0.1", 7070);
    tcpc.write('{action: "dirWatch", url:"D:/snailshop/wgu/"}');
    do{
        var cstr = tcpc.recv();
        console.log(cstr);
        
    } while(1)

    本来还想arrdio的文件监控,使用的是window api,相对的响应效果更好,但是在和nodejs信息传递方面还是存在很大的难度,不是我这个前端知识面能解决的问题。只能放弃了。

    chokidar 即 gulp-watch监控文件的方面也不错,性能上面有些消耗,但是用起来应该不受太大影响

  • 相关阅读:
    Python基础之函数与装饰器
    Python基础(字符编码与文件处理)
    周末练习(一)
    字典(习题)
    IOS代码库
    (转载)二叉树
    单链表的初始化和创建(尾插法)
    (转载)C语言单链表实现19个功能完全详解
    (转载)ios view的frame和bounds之区别(位置和大小)
    (转载)OC语法总结
  • 原文地址:https://www.cnblogs.com/legu/p/5827395.html
Copyright © 2011-2022 走看看