zoukankan      html  css  js  c++  java
  • Windows下文件的监控

    Windows 2000 引入了两个新接口,FindFirstChangeNotification 和 ReadDirectoryChangesW 。 FindFirstChangeNotification 很容易使用,但没有给出变更文件的信息。即便如此,这个函数对某些应用程序还是很有用的,比如传真服务和 SMTP 服务可以通过拖拽一个文件到一个目录来接受任务队列。ReadDirectoryChangesW 会给出变更的内容和方式, 不过相对的,在使用上也更复杂一些。

    1.FindFirstChangeNotification()函数

    功能:创建一个改变通知句柄,并设置通知条件,即发生某种修改时,该通知句柄将被促发生效。该函数仅仅负责对文件修改作出通知,并不记录和反馈修改信息。

    返回值:成功时返回指向改变通知的句柄,失败时返回INVALID_HANDLE_VALUE,可以用GetLastError()函数得到。

    例子:部分代码如下

    //使用FindFirstChangeNotification和FindNextChangeNotification实现文件监控
    CString Monitor1()
    {
    HANDLE hEvent;//监控句柄
    //char* path[MAX_PATH+1] ;//监控目录
    static int m_nCount = 0; //当前操作的序号
    CString str;

    //GetCurrentDirectory(MAX_PATH, (LPWSTR)path);
    hEvent = FindFirstChangeNotification("E:\",TRUE,FILE_NOTIFY_CHANGE_FILE_NAME| //查看指定目录下任何文件名的改变
    FILE_NOTIFY_CHANGE_DIR_NAME| //查看指定目录下任何目录名的改变
    FILE_NOTIFY_CHANGE_SIZE| //查看指定文件大小的改变
    FILE_NOTIFY_CHANGE_ATTRIBUTES);//查看指定目录下文件属性的改变
    if (hEvent == INVALID_HANDLE_VALUE)
    {
    //ExitProcess(GetLastError());//获取错误
    //return;
    str.Format("%s %s", "error", GetLastError());
    return str;
    }
    //while (TRUE)//循环监控
    {
    DWORD nobj;
    nobj= WaitForSingleObject(hEvent,INFINITE);//等待,文件夹任何动作,都返回0,顾不能知道具体动作和具体哪个文件发生了变化
    if (nobj)
    {
    ;
    }
    m_nCount++;
    str.Format("%d %s", m_nCount, "文件发生了变化!");
    printf("文件发生了变化 ");

    //继续监控
    if(FALSE==FindNextChangeNotification(hEvent))
    {
    //ExitProcess(GetLastError());
    //return;
    str.Format("%s %s", "error", GetLastError());
    return str;
    }
    }
    return str;
    }

    2.ReadDirectoryChangesW()函数

    功能:监控文件修改,并记录文件修改的相关信息,如修改的文件名,何种类型的修改等。

    返回值:如果函数成功,返回值就是非0。对于同步调用,这意味着操作成功,对于异步调用,这意味着操作成功地排队。如果函数失败,返回值是0。如果操作目录或文件系统不支持这个操作,函数将返回ERROR_INVALID_FUNCTION,可以使用GetLastError()函数获取。

    例子:部分代码如下

    //使用ReadDirectoryChangesW实现文件监控
    CString Monitor2()
    {
    DWORD cbBytes;
    char cFileName[1024]; //设置文件名
    char cNewFileName[1024]; //设置文件重命名后的名字
    char cNotify[1024];
    static int m_nCount = 0; //当前操作的序号
    TCHAR *pDirectory = "E:\";//m_strAddress.GetBuffer(m_strAddress.GetLength());

    CString str;
    HANDLE dirHandle;
    dirHandle = CreateFile(
    pDirectory,
    GENERIC_READ | GENERIC_WRITE | FILE_LIST_DIRECTORY,
    FILE_SHARE_READ | FILE_SHARE_WRITE,
    NULL,
    OPEN_EXISTING,
    FILE_FLAG_BACKUP_SEMANTICS,
    NULL);

    memset(cNotify, 0, strlen(cNotify));

    FILE_NOTIFY_INFORMATION *pNotify = (FILE_NOTIFY_INFORMATION*)cNotify;

    //若网络重定向或目标文件系统不支持该操作,函数失败,同时调用GetLastError()返回ERROR_INVALID_FUNCTION
    if(dirHandle == INVALID_HANDLE_VALUE)
    {
    str.Format("%s %s", "error", GetLastError());
    return str;
    }

    if(ReadDirectoryChangesW(
    dirHandle,
    &cNotify,
    1024,
    true,
    FILE_NOTIFY_CHANGE_FILE_NAME |
    FILE_NOTIFY_CHANGE_DIR_NAME
    //| FILE_NOTIFY_CHANGE_CREATION
    //| FILE_NOTIFY_CHANGE_LAST_WRITE
    | FILE_NOTIFY_CHANGE_SIZE,
    &cbBytes,NULL,NULL))
    {
    //转换文件名为多字节字符串
    if(pNotify->FileName)
    {
    memset(cFileName, 0, strlen(cFileName));
    WideCharToMultiByte(CP_ACP, 0, pNotify->FileName, pNotify->FileNameLength/2, cFileName, 99, NULL, NULL);
    }

    //获取重命名的文件名
    if(pNotify->NextEntryOffset != 0 && (pNotify->FileNameLength > 0 && pNotify->FileNameLength < MAX_PATH))
    {
    PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify + pNotify->NextEntryOffset);
    memset(cNewFileName, 0, sizeof(cNewFileName));
    WideCharToMultiByte(CP_ACP, 0, p->FileName, p->FileNameLength/2, cNewFileName, 99, NULL, NULL);
    }

    //设置类型过滤器,监听文件创建、更改、删除、重命名等
    switch(pNotify->Action)
    {
    case FILE_ACTION_ADDED:
    m_nCount++;
    str.Format("%d %s %s", m_nCount, "file add:", cFileName);
    //AfxMessageBox(str);
    break;
    case FILE_ACTION_MODIFIED:
    m_nCount++;
    str.Format("%d %s %s", m_nCount, "file modified:", cFileName);
    //AfxMessageBox(str);
    break;
    case FILE_ACTION_REMOVED:
    m_nCount++;
    str.Format("%d %s %s", m_nCount, "file removed:", cFileName);
    //AfxMessageBox(str);
    break;
    case FILE_ACTION_RENAMED_OLD_NAME:
    m_nCount++;
    str.Format("%d %s %s %s %s", m_nCount, "file renamed:", cFileName, "->", cNewFileName);
    //AfxMessageBox(str);
    break;

    default:
    //MessageBox("unknow command!");
    break;
    }
    CloseHandle(dirHandle);
    }
    return str;
    }

  • 相关阅读:
    JS BOM对象 History对象 Location对象
    JS 字符串对象 数组对象 函数对象 函数作用域
    JS 引入方式 基本数据类型 运算符 控制语句 循环 异常
    Pycharm Html CSS JS 快捷方式创建元素
    CSS 内外边距 float positio属性
    CSS 颜色 字体 背景 文本 边框 列表 display属性
    【Android】RxJava的使用(三)转换——map、flatMap
    【Android】RxJava的使用(二)Action
    【Android】RxJava的使用(一)基本用法
    【Android】Retrofit 2.0 的使用
  • 原文地址:https://www.cnblogs.com/zerotoinfinity/p/6387669.html
Copyright © 2011-2022 走看看