nodejs使用C++扩展实现监听文件目录变化

实现 nodejs代码能够监听文件目录变化,C++扩展代码如下

#include <iostream>
#include <nan.h>
#include <map>
#include "../deps/efsw/include/efsw/efsw.hpp"

namespace __watch__ {

using v8::Array;
using v8::Local;
using v8::Value;
using v8::Isolate;
using v8::Context;
using namespace std;

#define Watch watch
#define AddWatch addWatch
#define HandleFileAction handleFileAction
#define GetLastErrorLog getLastErrorLog

efsw::FileWatcher* file_watcher;

struct AsyncArgs {
    efsw::WatchID watch_id;
    std::string dir;
    std::string filename;
    efsw::Action action;
    std::string old_filename;
    uv_async_t handle;
    Nan::Callback* callback;
};

void OnAsyncClosed(uv_handle_t* handle)
{
    uv_async_t* async = (uv_async_t*)handle;
    AsyncArgs* data = (AsyncArgs*)async->data;
    delete data;
}

void OnEvent(uv_async_t* handle)
{
    printf("in OnEvent1\n");
    Nan::HandleScope scope;
    AsyncArgs* data = (AsyncArgs*)handle->data;
    Local<Value> argv[] = {
        Nan::New((int)data->watch_id),
        Nan::New(data->dir.c_str()).ToLocalChecked(),
        Nan::New(data->filename.c_str()).ToLocalChecked(),
        Nan::New(data->action),
        Nan::New(data->old_filename.c_str()).ToLocalChecked()
    };
    data->callback->Call(5, argv);
    uv_close((uv_handle_t*)handle, OnAsyncClosed);
    printf("in OnEvent2\n");
}

class UpdateListener : public efsw::FileWatchListener {
public:
    UpdateListener(Nan::Callback* callback) :
        callback(callback)
    {
    }

    ~UpdateListener()
    {
        Nan::HandleScope scope;
        delete callback;
    }

    void HandleFileAction(
            efsw::WatchID watchid,
            const std::string& dir,
            const std::string& filename,
            efsw::Action action,
            std::string old_filename)
    {

        printf("in HandleFileAction1\n");
        AsyncArgs* args = new AsyncArgs();
        args->watch_id = watchid;
        args->dir = dir;
        args->filename = filename;
        args->action = action;
        args->old_filename = old_filename;
        args->callback = callback;
        uv_async_init(uv_default_loop(), &args->handle, OnEvent);
        args->handle.data = (void*)args;
      //  _sleep(3*1000);
        int res = uv_async_send(&args->handle);
        std::cout << res;
        printf("\n");
        printf("in HandleFileAction2\n");
    }

private:
    Nan::Callback* callback;
};

std::map<std::string, std::vector<UpdateListener*> > listeners;

NAN_METHOD(Watch)
{
    if(info.Length() < 2 || !info[0]->IsString() || !info[1]->IsFunction())
    {
        return Nan::ThrowError("Wrong argument");
    }

    Isolate* isolate = Isolate::GetCurrent();
    Local<Context> context = isolate->GetCurrentContext();

    Nan::Utf8String path(info[0]->ToString(context).ToLocalChecked());
    Nan::Callback* callback = new Nan::Callback(info[1].As<v8::Function>());

    UpdateListener* listener = new UpdateListener(callback);
    listeners[*path].push_back(listener);

    efsw::WatchID watch_id = file_watcher->AddWatch(*path, listener, true);

    if(watch_id < 0)
    {
        return Nan::ThrowError(efsw::Errors::Log::GetLastErrorLog().c_str());
    }

    info.GetReturnValue().Set(Nan::New((int)watch_id));
}

NAN_MODULE_INIT(Init)
{

    file_watcher = new efsw::FileWatcher();
    file_watcher->Watch();

    Nan::Export(target, "watch", Watch);
}

NODE_MODULE(watch, Init)

}

nodejs调用代码

const obj = require("./build/Release/watch");
const fs = require('fs');
console.log('obj',obj);

obj.watch('/tmp',function(){//监听/tmp目录变化,如果目录中文件改变则执行回调
    debugger;
    console.log('tmp is call....');
    console.log(arguments);
});


function second()
{
    // 写回文件
    fs.writeFile("D:/tmp/1.txt", "777", 'utf8', (writeErr) => {
        if (writeErr) {
        return console.error(writeErr);
        }
        console.log('文件已修改');
    });
}

setTimeout(second,2000);

function abc()
{
    console.log("abc=================================");
}

setTimeout(abc,3000);//JS主线程退出了,则不会执行到第6行代码 这里延迟要大于上面setTimeout的延迟



// console.log("111111111111111111111111112");

// while(true){//这种JS主线程卡住了,无法回调

// }

// obj.watch('/tmp/sdfkjl',function(){
//     console.log(arguments);
// });


//流程
//监听目录文件变化-->目录文件发生改变-->c++代码回调JS函数-->JS主线程执行回调函数(JS主线程退出或卡住则无法执行回调)

测试结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

liberty888

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值