我试图用来ReadDirectoryChangesW
跟踪文件何时被创建、复制或移动到受监视的目录。
我的问题是,当我在受监视目录上复制或创建文件时,没有捕获ReadDirectoryChangesW
FILE_ACTION_ADDED 事件,而是仅捕获 FILE_ACTION_MODIFIED 事件。
另一方面,当我将文件(而不是复制或创建)从另一个目录移动到受监视的目录时,会捕获 FILE_ACTION_ADDED。
我想知道是否有人知道一种方法可以让 ReadDirectoryChangesW 在我的 3 个案例中捕获 FILE_ACTION_ADDED:创建、复制和移动。
我ReadDirectoryChangesW
这样称呼:
ReadDirectoryChangesW(directory_handle, buffer, MAX_EVENTs_BUFFER,
FALSE, FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME |
FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_SIZE,
NULL, (LPOVERLAPPED)usr_data, FileIOCompletionRoutine)
我CreateFileA
用来初始化directory_handle
:
CreateFileA(directory_path.c_str(),
FILE_LIST_DIRECTORY, FILE_SHARE_READ | FILE_SHARE_WRITE |
FILE_SHARE_DELETE, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS |
FILE_FLAG_OVERLAPPED, NULL);
然后,FileIOCompletionRoutine
当我将文件复制到受监视的目录或创建文件时,我永远不会收到 FILE_ACTION_ADDED ,只有当我移动文件时。这是正常行为还是我做错了什么?
编辑1:
VOID CALLBACK FileIOCompletionRoutine(_In_ DWORD err, _In_ DWORD bytes, _Inout_ LPOVERLAPPED lpOverlapped)
{
CUSTOM_OVERLAPPED* pCustomOverlapped = (CUSTOM_OVERLAPPED*)lpOverlapped;
char* buffer_offset = (char*)pCustomOverlapped->buffer;
PFILE_NOTIFY_INFORMATION pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;
do
{
pInfo = (PFILE_NOTIFY_INFORMATION)buffer_offset;
switch (pInfo->Action)
{
case FILE_ACTION_ADDED:
{
std::cout << "file added!\n";
break;
}
case FILE_ACTION_MODIFIED:
{
std::cout << "file modified!\n";
break;
}
// and so on...
}
buffer_offset += pInfo->NextEntryOffset;
} while(pInfo->NextEntryOffset);
}
编辑2:
我发现如果我FILE_NOTIFY_CHANGE_LAST_WRITE
从创建新文件和执行剪切和粘贴时正确捕获事件ReadDirectoryChangesW
中删除FILE_ACTION_ADDED
,但如果我执行复制和粘贴则不会在这种情况下触发FILE_ACTION_MODIFIED
. 为了FILE_ACTION_ADDED
在我复制并粘贴到受监控的目录时获得一个,我也需要删除该FILE_NOTIFY_CHANGE_SIZE
标志。
因此,如果想要在受监视目录中跟踪新文件(创建、复制或移动),我只需要函数FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_DIR_NAME
上的标志。ReadDirectoryChangesW
如果我想跟踪我需要的修改过的(已经存在于目录中)文件FILE_NOTIFY_CHANGE_SIZE
,但我不能使用三个标志中的一个或三个标志ReadDirectoryChangesW
来跟踪新文件和修改过的文件。
你们中的任何人是否找到了一种方法来使用三个标志的逻辑或三个标志来跟踪所有这些事件,或者我是否必须ReadDirectoryChangesW
为每种情况调用不同的标志?