1

ディレクトリを監視するために 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;
                }
            }
        }

問題ないように見えますが、ディレクトリに多数のファイルを追加または削除すると、一部の変更が報告されません。これを修正するにはどうすればよいですか?

4

1 に答える 1

1

バッファを大きくしてみてください。

ReadDirectoryChangesW 関数のドキュメントから:

最初に ReadDirectoryChangesW を呼び出すと、システムは変更情報を格納するためのバッファーを割り当てます。このバッファは、閉じられるまでディレクトリ ハンドルに関連付けられており、そのサイズは有効期間中変更されません。この関数の呼び出しの間に発生するディレクトリの変更はバッファーに追加され、次の呼び出しで返されます。バッファーがオーバーフローした場合、バッファーの内容全体が破棄され、lpBytesReturned パラメーターにはゼロが含まれます。

システムが割り当てるバッファ サイズは、渡されたバッファのサイズに基づいています。より大きなサイズを渡した場合、以前の多くの変更を処理している間に発生した変更を格納するために、システムはより大きなバッファを割り当てます。つまり、バッファがオーバーフローして変更が失われる可能性が低くなります。

于 2012-08-20T12:13:24.953 に答える