设为首页 收藏本站
查看: 3633|回复: 0

[经验分享] Windows下文件的监控

[复制链接]

尚未签到

发表于 2017-12-8 16:00:48 | 显示全部楼层 |阅读模式
  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("文件发生了变化\r\n");

        //继续监控
        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;
}

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-422190-1-1.html 上篇帖子: ArcGIS 网络分析[3] 发布NAServer到ArcGIS for Server(以Server 10.4为例) 下篇帖子: 背水一战 Windows 10 (55)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表