因为文章已经在VCKBASE上发表过,故尔这里仅给出链接http://www.vckbase.com/document/viewdoc.asp?id=814// 2007-12-14 整理(使用VC2005)@FileSystemWatcher.hpp#ifndef __FILESYSTEMWATCHER_HPP__#define __FILESYSTEMWATCHER_HPP__#if(_WIN32_WINNT #define _WIN32_WINNT0x0400#endif#includeclass FileSystemWatcher{public:    enum Filter   {        FILTER_FILE_NAME        = 0x00000001, //add/remove/rename        FILTER_DIR_NAME         = 0x00000002, //add/remove/rename        FILTER_ATTR_NAME        = 0x00000004,       FILTER_SIZE_NAME        = 0x00000008,        FILTER_LAST_WRITE_NAME  =0x00000010, // timestamp        FILTER_LAST_ACCESS_NAME = 0x00000020, //timestamp        FILTER_CREATION_NAME    = 0x00000040, //timestamp        FILTER_SECURITY_NAME    = 0x00000100    };    enumACTION    {        ACTION_ERRSTOP          = -1,       ACTION_ADDED            = 0x00000001,        ACTION_REMOVED          =0x00000002,        ACTION_MODIFIED         = 0x00000003,       ACTION_RENAMED_OLD      = 0x00000004,        ACTION_RENAMED_NEW      =0x00000005    };    typedef void (__stdcall *LPDEALFUNCTION)( ACTION act, LPCWSTR filename,LPVOID lParam );    FileSystemWatcher();    ~FileSystemWatcher();    // LPCTSTR dir: ended-with "\\"    boolRun( LPCTSTR dir, bool bWatchSubtree, DWORD dwNotifyFilter, LPDEALFUNCTIONdealfun, LPVOID lParam );    void Close( DWORD dwMilliseconds=INFINITE);private: // no-impl    FileSystemWatcher( const FileSystemWatcher&);    FileSystemWatcher operator=( const FileSystemWatcher );private:    HANDLE m_hDir;    DWORD m_dwNotifyFilter;    boolm_bWatchSubtree;    HANDLE m_hThread;    volatile boolm_bRequestStop;    LPDEALFUNCTION m_DealFun;    LPVOIDm_DealFunParam;    static DWORD WINAPI Routine( LPVOID lParam );};#endif // [email protected]#include #include "FileSystemWatcher.hpp"FileSystemWatcher::FileSystemWatcher() : m_hDir(INVALID_HANDLE_VALUE),m_hThread(NULL){    assert( FILTER_FILE_NAME        ==FILE_NOTIFY_CHANGE_FILE_NAME   );    assert( FILTER_DIR_NAME         ==FILE_NOTIFY_CHANGE_DIR_NAME    );    assert( FILTER_ATTR_NAME        ==FILE_NOTIFY_CHANGE_ATTRIBUTES  );    assert( FILTER_SIZE_NAME        ==FILE_NOTIFY_CHANGE_SIZE        );    assert( FILTER_LAST_WRITE_NAME  ==FILE_NOTIFY_CHANGE_LAST_WRITE  );    assert( FILTER_LAST_ACCESS_NAME ==FILE_NOTIFY_CHANGE_LAST_ACCESS );    assert( FILTER_CREATION_NAME    ==FILE_NOTIFY_CHANGE_CREATION    );    assert( FILTER_SECURITY_NAME    ==FILE_NOTIFY_CHANGE_SECURITY    );    assert( ACTION_ADDED            == FILE_ACTION_ADDED             );    assert( ACTION_REMOVED          == FILE_ACTION_REMOVED           );    assert( ACTION_MODIFIED         == FILE_ACTION_MODIFIED          );    assert( ACTION_RENAMED_OLD      == FILE_ACTION_RENAMED_OLD_NAME  );    assert( ACTION_RENAMED_NEW      == FILE_ACTION_RENAMED_NEW_NAME  );}FileSystemWatcher::~FileSystemWatcher(){    Close();}bool FileSystemWatcher::Run( LPCTSTR dir, bool bWatchSubtree, DWORDdwNotifyFilter, LPDEALFUNCTION dealfun, LPVOID lParam ){    Close();    m_hDir = CreateFile(        dir,        GENERIC_READ,       FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,        NULL,       OPEN_EXISTING,        FILE_FLAG_BACKUP_SEMANTICS,        NULL   );    if( INVALID_HANDLE_VALUE == m_hDir ) return false;    m_bWatchSubtree = bWatchSubtree;    m_dwNotifyFilter =dwNotifyFilter;    m_DealFun = dealfun;    m_DealFunParam =lParam;    m_bRequestStop = false;    DWORD ThreadId;    m_hThread = CreateThread(NULL,0,Routine,this,0,&ThreadId );    if( NULL == m_hThread )   {        CloseHandle( m_hDir );        m_hDir =INVALID_HANDLE_VALUE;    }    return NULL!=m_hThread;}void FileSystemWatcher::Close( DWORD dwMilliseconds ){    if( NULL !=m_hThread )    {        m_bRequestStop = true;        if(WAIT_TIMEOUT == WaitForSingleObject(m_hThread,dwMilliseconds) )           TerminateThread( m_hThread, 0 );        CloseHandle( m_hThread );       m_hThread = NULL;    }    if( INVALID_HANDLE_VALUE != m_hDir )   {        CloseHandle( m_hDir );        m_hDir =INVALID_HANDLE_VALUE;    }}DWORD WINAPI FileSystemWatcher::Routine( LPVOID lParam ){   FileSystemWatcher& obj = *(FileSystemWatcher*)lParam;    BYTE buf[ 2*(sizeof(FILE_NOTIFY_INFORMATION)+2*MAX_PATH)+2 ];   FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;    DWORDBytesReturned;    while( !obj.m_bRequestStop )    {        if(ReadDirectoryChangesW( obj.m_hDir,            pNotify,           sizeof(buf)-2,            obj.m_bWatchSubtree,           obj.m_dwNotifyFilter,            &BytesReturned,           NULL,            NULL ) ) //无限等待,应当使用异步方式        {            for( FILE_NOTIFY_INFORMATION*p=pNotify; p; )            {                WCHAR c =p->FileName[p->FileNameLength/2];               p->FileName[p->FileNameLength/2] = L'\0';                obj.m_DealFun( (ACTION)p->Action, p->FileName,obj.m_DealFunParam );                p->FileName[p->FileNameLength/2] = c;                if( p->NextEntryOffset )                    p  =(PFILE_NOTIFY_INFORMATION)( (BYTE*)p + p->NextEntryOffset);                else                    p = 0;           }        }        else        {            obj.m_DealFun((ACTION)ACTION_ERRSTOP, 0, obj.m_DealFunParam );           break;        }    }    return 0;}@test.cpp#include "FileSystemWatcher.hpp"#include #include#include #include#includevoid __stdcall MyDeal( FileSystemWatcher::ACTION act, LPCWSTR filename,LPVOID lParam ){    static FileSystemWatcher::ACTION pre =FileSystemWatcher::ACTION_ERRSTOP;    switch( act )    {    caseFileSystemWatcher::ACTION_ADDED:        wprintf_s( L"Added     - %s\n",filename );        break;    caseFileSystemWatcher::ACTION_REMOVED:        wprintf_s( L"Removed   - %s\n",filename );        break;    caseFileSystemWatcher::ACTION_MODIFIED:        wprintf_s( L"Modified  - %s\n",filename );        break;    caseFileSystemWatcher::ACTION_RENAMED_OLD:        wprintf_s( L"Rename(O) -%s\n", filename );        break;    caseFileSystemWatcher::ACTION_RENAMED_NEW:        assert( pre ==FileSystemWatcher::ACTION_RENAMED_OLD );        wprintf_s( L"Rename(N) -%s\n", filename );        break;    caseFileSystemWatcher::ACTION_ERRSTOP:    default:        wprintf_s(L"---ERROR---%s\n", filename );        break;    }    pre =act;}int main(){    LPCTSTR sDir= TEXT("F:\\temp\\cpp06\\test\\");   DWORD dwNotifyFilter =FileSystemWatcher::FILTER_FILE_NAME|FileSystemWatcher::FILTER_DIR_NAME;    FileSystemWatcher fsw;    bool r = fsw.Run( sDir, true,dwNotifyFilter, &MyDeal, 0 );    if( !r ) return -1;    _tsetlocale( LC_CTYPE, TEXT("chs") );    _tprintf_s(TEXT("Watch%s\n"), sDir );    _tprintf_s( TEXT("Press to quit.\n"));    while( _getch() != 'q' );    fsw.Close();    return 0;} 
11-08 06:28