因为文章已经在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