目录监测的讨论
2006-07-20 11:39:07 来源:WEB开发网核心提示:测试VC知识库中周星星所写的《目录监测》一文所提供的程序,发现有一些不够完善的地方,遂写出与大家共同探讨,目录监测的讨论,问题:原程序中在处理多个文件拷贝和山删除时不能完全显示,如对200个文件进行拷贝:copy temp\*.txt仅能监控到3个文件变化,目前发现拷贝时对同一个文件有5个 FILE_ACTION_AD
测试VC知识库中周星星所写的《目录监测》一文所提供的程序,发现有一些不够完善的地方,遂写出与大家共同探讨。
问题:
原程序中在处理多个文件拷贝和山删除时不能完全显示,如对200个文件进行拷贝:
copy temp\*.txt
仅能监控到3个文件变化,目前发现拷贝时对同一个文件有5个 FILE_ACTION_ADDED 显示
( 测试环境: Microsoft Windows 2000 [Version 5.00.2195] )
一、对FileSystemWatcher.h 的改进:
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <string>
#include <cassert>
void SendOutNotify(PFILE_NOTIFY_INFORMATION f_pNotify);
#define DeFileWaterBuffer (1000* (sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) )
enum ACTION { ADDED=1, REMOVED=2, MODIFIED=3, RENAMED=4 };
class FileSystemWatcher
{
public:
typedef void (__stdcall *LPDEALFUNCTION)( ACTION act, std::string filename1, std::string filename2 );
bool Run( std::string path, LPDEALFUNCTION dealfun )
{
WatchedDir = path;
DealFun = dealfun;
DWORD ThreadId;
//hThread=CreateThread( NULL,0,Routine,this,0,&ThreadId );
hThread=CreateThread( NULL,0,RoutineTest,this,0,&ThreadId );
return NULL!=hThread;
}
void Close()
{
if( NULL != hThread )
{
TerminateThread( hThread, 0 );
hThread = NULL;
}
if( INVALID_HANDLE_VALUE != hDir )
{
CloseHandle( hDir );
hDir = INVALID_HANDLE_VALUE;
}
}
FileSystemWatcher() : DealFun(NULL), hThread(NULL), hDir(INVALID_HANDLE_VALUE)
{
}
~FileSystemWatcher()
{
Close();
}
private:
std::string WatchedDir;
LPDEALFUNCTION DealFun;
HANDLE hThread;
HANDLE hDir;
private:
FileSystemWatcher( const FileSystemWatcher& );
FileSystemWatcher operator=( const FileSystemWatcher );
private:
static DWORD WINAPI Routine( LPVOID lParam )
{
FileSystemWatcher* obj = (FileSystemWatcher*)lParam;
/*
obj->hDir = CreateFile(
obj->WatchedDir.c_str(),
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS,
NULL
);
*/
//hcs change
obj->hDir = CreateFile(
obj->WatchedDir.c_str(), // pointer to the file name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);
if( INVALID_HANDLE_VALUE == obj->hDir ) return false;
char buf[ 50*(sizeof(FILE_NOTIFY_INFORMATION)+MAX_PATH) ];
FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)buf;
DWORD BytesReturned;
while(true)
{
memset(buf,0,sizeof(buf));
if( ReadDirectoryChangesW( obj->hDir,
pNotify,
sizeof(buf),
true,
FILE_NOTIFY_CHANGE_FILE_NAME|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_SECURITY,
&BytesReturned,
NULL,
NULL ) )
{
/*
char tmp[MAX_PATH], str1[MAX_PATH], str2[MAX_PATH];
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str1, tmp );
if( 0 != pNotify->NextEntryOffset )
{
PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset);
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,p->FileName,p->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str2, tmp );
}
obj->DealFun( (ACTION)pNotify->Action, str1, str2 );
*/
SendOutNotify(pNotify);
}
else
{
break;
}
}
return 0;
}
static DWORD WINAPI RoutineTest( LPVOID lParam )
{
FileSystemWatcher* obj = (FileSystemWatcher*)lParam;
//hcs change
obj->hDir = CreateFile(
obj->WatchedDir.c_str(), // pointer to the file name
FILE_LIST_DIRECTORY, // access (read/write) mode
FILE_SHARE_READ|FILE_SHARE_DELETE, // share mode
NULL, // security descriptor
OPEN_EXISTING, // how to create
FILE_FLAG_BACKUP_SEMANTICS, // file attributes
NULL // file with attributes to copy
);
if( INVALID_HANDLE_VALUE == obj->hDir ) return false;
char *pcBufferNs=new char[DeFileWaterBuffer];
FILE_NOTIFY_INFORMATION* pNotify=(FILE_NOTIFY_INFORMATION *)pcBufferNs;
DWORD BytesReturned;
while(true)
{
memset(pcBufferNs,0,DeFileWaterBuffer);
BytesReturned=0;
if(
ReadDirectoryChangesW(
obj->hDir,
pNotify,
DeFileWaterBuffer,
true,
FILE_NOTIFY_CHANGE_FILE_NAME|
FILE_NOTIFY_CHANGE_DIR_NAME|
FILE_NOTIFY_CHANGE_ATTRIBUTES|
FILE_NOTIFY_CHANGE_SIZE|
FILE_NOTIFY_CHANGE_LAST_WRITE|
FILE_NOTIFY_CHANGE_LAST_ACCESS|
FILE_NOTIFY_CHANGE_CREATION|
FILE_NOTIFY_CHANGE_SECURITY,
&BytesReturned,
NULL,
NULL ) )
{
/*
char tmp[MAX_PATH], str1[MAX_PATH], str2[MAX_PATH];
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,pNotify->FileName,pNotify->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str1, tmp );
if( 0 != pNotify->NextEntryOffset )
{
PFILE_NOTIFY_INFORMATION p = (PFILE_NOTIFY_INFORMATION)((char*)pNotify+pNotify->NextEntryOffset);
memset( tmp, 0, sizeof(tmp) );
WideCharToMultiByte( CP_ACP,0,p->FileName,p->FileNameLength/2,tmp,99,NULL,NULL );
strcpy( str2, tmp );
}
obj->DealFun( (ACTION)pNotify->Action, str1, str2 );
*/
if(BytesReturned> 0)
{
SendOutNotify(pNotify);
}
else
{
//AfxMessageBox("Buffer is small");
MessageBox(0,"Buffer is small","error",MB_OK);
}
}
else
{
break;
}
}
delete [] pcBufferNs;
return 0;
}
};
二、对FileSystemWatcher.cpp 的改进: #include "stdafx.h"
#include <conio.h>
#include <iostream>
#include "FileSystemWatcher.h"
using namespace std;
static int g_nChangeTimes;
void __stdcall MyDeal( ACTION act, std::string filename1, std::string filename2 )
{
g_nChangeTimes++;
/*
switch( act )
{
case ADDED:
cout << "Added - " << filename1 << endl;
break;
case REMOVED:
cout << "Removed - " << filename1 << endl;
break;
case MODIFIED:
cout << "Modified - " << filename1 << endl;
break;
case RENAMED:
cout << "Rename - " << filename1 << " " << filename2 << endl;
break;
}
*/
}
void main()
{
FileSystemWatcher a;
//a.Run( "D:\\", MyDeal );
//cout << "Watch D:\\" << endl;
a.Run( "C:\\", MyDeal );
cout << "Watch C:\\" << endl;
cout << "Press <q> to quit." << endl;
while(getch()!=''q'');
a.Close();
}
//hcs add use for test file change
void SendOutNotify(PFILE_NOTIFY_INFORMATION f_pNotify)
{
PFILE_NOTIFY_INFORMATION pNextNotify=f_pNotify ;
char pcfilename[MAX_PATH];
for(int i=0;i<5000;i++)
{
g_nChangeTimes++;
memset(pcfilename , 0, MAX_PATH );
WideCharToMultiByte( CP_ACP,0,pNextNotify->FileName,pNextNotify->FileNameLength/2,pcfilename,MAX_PATH,NULL,NULL );
//*(pcfilename+f_pNotify->FileNameLength)=0;
switch( f_pNotify->Action )
{
case FILE_ACTION_ADDED:
cout << "Added - " << pcfilename << endl;
break;
case FILE_ACTION_REMOVED:
cout << "Removed - " << pcfilename << endl;
break;
case FILE_ACTION_MODIFIED:
cout << "Modified - " << pcfilename << endl;
break;
case FILE_ACTION_RENAMED_OLD_NAME:
cout << "Rename - " << pcfilename << " " << "filename2" << endl;
break;
case FILE_ACTION_RENAMED_NEW_NAME:
cout << "RenameNew - " << pcfilename << " " << "filename2" << endl;
break;
}
cout << "Message Times is" << i << " File Len is "<< g_nChangeTimes << endl;;
//pNextNotify->FileNameLength << endl;
if(pNextNotify->NextEntryOffset)
{
pNextNotify=(PFILE_NOTIFY_INFORMATION)((char*)pNextNotify+pNextNotify->NextEntryOffset);
}
else
{
break;
}
}
return;
}
更多精彩
赞助商链接