您的位置:首页 > 其它

[Windows]_[初级]_[监听指定目录文件夹中文件的变化]

2016-01-28 19:48 423 查看
主要是用函数ReadDirectoryChangesW来进行监听文件的变化。
函数原型:
BOOL WINAPI ReadDirectoryChangesW(
_In_        HANDLE                          hDirectory,
_Out_       LPVOID                          lpBuffer,
_In_        DWORD                           nBufferLength,
_In_        BOOL                            bWatchSubtree,
_In_        DWORD                           dwNotifyFilter,
_Out_opt_   LPDWORD                         lpBytesReturned,
_Inout_opt_ LPOVERLAPPED                    lpOverlapped,
_In_opt_    LPOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);

Parameters

hDirectory [in]A handle to the directory to be monitored. This directory must be opened with the FILE_LIST_DIRECTORY access right.
lpBuffer [out]A pointer to the DWORD-aligned formatted buffer in which the read results are to be returned. The structure of this buffer is defined by the FILE_NOTIFY_INFORMATION structure. This buffer is filled either synchronously or asynchronously, depending on how the directory is opened and what value is given to the lpOverlapped parameter. For more information, see the Remarks section.
nBufferLength [in]The size of the buffer that is pointed to by the lpBuffer parameter, in bytes.
bWatchSubtree [in]If this parameter is TRUE, the function monitors the directory tree rooted at the specified directory. If this parameter is FALSE, the function monitors only the directory specified by the hDirectory parameter.
dwNotifyFilter [in]The filter criteria that the function checks to determine if the wait operation has completed. This parameter can be one or more of the following values.
ValueMeaning
FILE_NOTIFY_CHANGE_FILE_NAME0x00000001Any file name change in the watched directory or subtree causes a change notification wait operation to return. Changes include renaming, creating, or deleting a file.
FILE_NOTIFY_CHANGE_DIR_NAME0x00000002Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory.
FILE_NOTIFY_CHANGE_ATTRIBUTES0x00000004Any attribute change in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SIZE0x00000008Any file-size change in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change in file size only when the file is written to the disk. For operating systems that use extensive
caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_WRITE0x00000010Any change to the last write-time of files in the watched directory or subtree causes a change notification wait operation to return. The operating system detects a change to the last write-time only when the file is written to the disk. For
operating systems that use extensive caching, detection occurs only when the cache is sufficiently flushed.
FILE_NOTIFY_CHANGE_LAST_ACCESS0x00000020Any change to the last access time of files in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_CREATION0x00000040Any change to the creation time of files in the watched directory or subtree causes a change notification wait operation to return.
FILE_NOTIFY_CHANGE_SECURITY0x00000100Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return.
 
lpBytesReturned [out, optional]For synchronous calls, this parameter receives the number of bytes transferred into the lpBuffer parameter. For asynchronous calls, this parameter is undefined. You must use an asynchronous notification technique to retrieve the number of bytes transferred.
lpOverlapped [in, out, optional]A pointer to an OVERLAPPED structure that supplies data to be used during asynchronous operation. Otherwise, this value is NULL. The Offset and OffsetHigh members of this structure are not used.
lpCompletionRoutine [in, optional]A pointer to a completion routine to be called when the operation has been completed or canceled and the calling thread is in an alertable wait state. For more information about this completion routine, see FileIOCompletionRoutine.

如果函数成功,返回值是零。对于同步调用,这意味着操作成功了。对于异步调用,这表明操作成功排队。

下面是监控的实现:

void MonitorFolderChange(std::wstring file_path)
{
const int buf_size = 1024;
TCHAR buf[buf_size];

DWORD buffChangeSize;
HANDLE hDir;
hDir = CreateFile(file_path.c_str(), FILE_LIST_DIRECTORY, FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);

if (hDir == INVALID_HANDLE_VALUE)
{
DWORD dwErrorCode;
dwErrorCode = GetLastError();
CloseHandle(hDir);
exit(0);
}

while(true)
{
//如果没有监听到什么变化,就直接返回,并且退出函数,所以要实时监听可以开启一个线程来测试。
if(ReadDirectoryChangesW(hDir, &buf, buf_size, FALSE, FILE_NOTIFY_CHANGE_SIZE | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_ATTRIBUTES
, &buffChangeSize, NULL, NULL))
{
FILE_NOTIFY_INFORMATION * pfiNotifyInfo = (FILE_NOTIFY_INFORMATION*)buf;
DWORD dwNextEntryOffset;

dwNextEntryOffset = pfiNotifyInfo->NextEntryOffset;
DWORD dwAction = pfiNotifyInfo->Action;
DWORD dwFileNameLength = pfiNotifyInfo->FileNameLength;
std::wstring file_name =pfiNotifyInfo->FileName;
int n =file_name.find_last_of('.');
if(n>=0)
{
file_name =file_name.substr(0,n+4);
std::wstring changepath =file_path;
changepath.append(L"\\").append(file_name);
char *char_path =ConvertUnicodeToUtf8(changepath.c_str());
std::cout<<"修改的文件路径 path:"<<char_path<<std::endl;
free(char_path);
}
}
else
{
printf("Moniter Failed!\n");
}
}

CloseHandle(hDir);
}
注意(步骤):

1、通过CreateFile获取要监控的目录句柄。
2、通过ReadDirectoryChangesW来监测到文件系统的变化,还能够返回详细的文件变动的信息,并且能够选择是使用同步方式检测还是异步方式监测。
3、通过Action设置类型过滤器,根据过滤器的设置,ReadDirectoryChangesW函数可以监控文件名改变、文件属性改变、文件大小改变、文件内容被改写、文件被删除等多种类型的变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  windows 文件监听