主要是用函数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 );
A handle to the directory to be monitored. This directory must be opened with the FILE_LIST_DIRECTORY access right.
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.
The size of the buffer that is pointed to by the lpBuffer parameter, in bytes.
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.
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.
Value | Meaning |
---|---|
|
Any 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. |
|
Any directory-name change in the watched directory or subtree causes a change notification wait operation to return. Changes include creating or deleting a directory. |
|
Any attribute change in the watched directory or subtree causes a change notification wait operation to return. |
|
Any 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. |
|
Any 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. |
|
Any change to the last access time of files in the watched directory or subtree causes a change notification wait operation to return. |
|
Any change to the creation time of files in the watched directory or subtree causes a change notification wait operation to return. |
|
Any security-descriptor change in the watched directory or subtree causes a change notification wait operation to return. |
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.
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.
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:"<
注意(步骤):
1、通过CreateFile获取要监控的目录句柄。
2、通过ReadDirectoryChangesW来监测到文件系统的变化,还能够返回详细的文件变动的信息,并且能够选择是使用同步方式检测还是异步方式监测。
3、通过Action设置类型过滤器,根据过滤器的设置,ReadDirectoryChangesW函数可以监控文件名改变、文件属性改变、文件大小改变、文件内容被改写、文件被删除等多种类型的变化。