使用ReadDirectoryChangesW时丢失文件

时间:2012-08-20 10:37:18

标签: winapi

我正在使用ReadDirectoryChangesW来监控目录 这是我的简单代码

 #include <windows.h>
        #include <stdlib.h>
        #include <stdio.h>
        #include <tchar.h>
        #include <iostream>
        #include <string>
        #include <cwctype>

        using namespace std;
        wstring getname(FILE_NOTIFY_INFORMATION *tmp)
        {
            wstring s = L"";
            for (int i = 0;i < tmp->FileNameLength / 2;i++)
                s += tmp->FileName[i];
            return s;
        }
        void _tmain(int argc, TCHAR *argv[])
        {

            HANDLE hDir; 
            char notify[1024]; 
            DWORD cbBytes,i; 
            char AnsiChar[3]; 
            wchar_t UnicodeChar[2]; 
            LPTSTR path;

            FILE_NOTIFY_INFORMATION *pnotify=(FILE_NOTIFY_INFORMATION *)notify; 
            FILE_NOTIFY_INFORMATION *tmp ; 

        //    GetCurrentDirectory(MAX_PATH,path.GetBuffer(MAX_PATH+1));
            wcout.imbue(locale("chs"));
            path = argv[1];
            hDir = CreateFile( path, FILE_LIST_DIRECTORY,
                FILE_SHARE_READ | 
                FILE_SHARE_WRITE | 
                FILE_SHARE_DELETE, NULL, 
                OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS | 
                FILE_FLAG_OVERLAPPED, NULL); 
            wcout << L"===CreateFile complete===" << endl;
            if (hDir == INVALID_HANDLE_VALUE) 
            { 
                wcout << L"invalid handle value" << endl;       
                return;
            } 
            FILE_NOTIFY_INFORMATION buffer[1024];
            FILE_NOTIFY_INFORMATION *pbuffer;
            while (TRUE) 
            { 
                wcout << L"waiting..." << endl;
                if(ReadDirectoryChangesW(hDir, &buffer, sizeof(buffer),
                    TRUE, FILE_NOTIFY_CHANGE_FILE_NAME| FILE_NOTIFY_CHANGE_LAST_WRITE, 
                    &cbBytes, NULL, NULL)) 
                { 
                    pbuffer = buffer;
                    do{
                        tmp = pbuffer; 
                        switch(tmp->Action) 
                        { 
                        case FILE_ACTION_ADDED: 
                            wcout << L"Directory/File added - " << getname(tmp) << endl;
                            break; 
                        case FILE_ACTION_REMOVED:
                            wcout << L"Directory/File removed - " << getname(tmp) << endl;
                            break; 
                        case FILE_ACTION_MODIFIED: 
                            wcout << L"Directory/File modfied - " << getname(tmp) << endl;
                            break; 
                        case FILE_ACTION_RENAMED_OLD_NAME: 
                            wcout << L"Directory/File old name - " << getname(tmp) << endl;
                            break; 
                        case FILE_ACTION_RENAMED_NEW_NAME: 
                            wcout << L"Directory/File new name - " << getname(tmp) << endl;
                            break; 
                        default:
                            wcout << L"unknown action\n" << endl;
                            break; 
                        }
                        pbuffer += pbuffer->NextEntryOffset;
                    }while(pbuffer->NextEntryOffset);
                } else
                {
                    wcout << "readChangesW failed  now return" << endl;
                    return;
                }
            }
        }

看起来不错,但是,当我在目录中添加或删除大量文件时,它不会报告某些更改,我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

尝试让你的缓冲区更大。

来自ReadDirectoryChangesW函数的文档:

  

当您第一次调用ReadDirectoryChangesW时,系统会分配一个缓冲区来存储更改信息。此缓冲区与目录句柄关联,直到它关闭并且其大小在其生命周期内不会更改。在对此函数的调用之间发生的目录更改将添加到缓冲区,然后在下一次调用时返回。如果缓冲区溢出,则丢弃缓冲区的全部内容,并且lpBytesReturned参数包含零。

系统分配的缓冲区大小取决于传入的缓冲区大小。如果传入更大的大小,系统将分配更大的缓冲区来存储在处理前一批更改时发生的更改,这意味着缓冲区溢出的可能性更小,而且这些更改也会丢失。