目录监测的讨论

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

目录监测的讨论

作者:黄老邪

测试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;

}

(全文完)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
© 2005- 王朝网络 版权所有