我在我的Windows PC上使用winapi进行文件监视。我使用了使用CreateFile实现filewatcher的基本方法,ReadDirectoryChangesW和某些过滤器 FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE
在文件夹(目录)中创建文件时观察目录 filewatcher在创建文件时正常工作,重命名,复制除删除之外的所有内容。 shift delete在文件上正常工作。
我的代码
QString newDirName;
char buf[2048];
DWORD nRet;
BOOL result=TRUE;
char filename[MAX_PATH];
//path = L"K:/Demo/bb";
wchar_t* arr = (wchar_t*)path;
printf("\nThe file directory: [%s] \n", path);
qDebug() << "WatchDirectory Watcher Path " << QString::fromWCharArray(arr);
DirInfo[0].hDir = CreateFile (path, GENERIC_READ|FILE_LIST_DIRECTORY,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS,
NULL);
if(DirInfo[0].hDir == INVALID_HANDLE_VALUE)
{
qDebug() << "Can not open";
return;
}
lstrcpy( DirInfo[0].lpszDirName, path);
OVERLAPPED PollingOverlap;
FILE_NOTIFY_INFORMATION pNotify[1024];
int offset;
PollingOverlap.OffsetHigh = 0;
PollingOverlap.hEvent = CreateEvent(NULL,TRUE,FALSE,NULL);
while(result)
{
result = ReadDirectoryChangesW(
DirInfo[0].hDir,// handle to the directory to be watched
(LPVOID)&pNotify,// pointer to the buffer to receive the read results
sizeof(pNotify),// length of lpBuffer
1,// flag for monitoring directory or directory tree
FILE_NOTIFY_CHANGE_DIR_NAME | FILE_NOTIFY_CHANGE_LAST_WRITE | FILE_NOTIFY_CHANGE_FILE_NAME | FILE_NOTIFY_CHANGE_SIZE ,
&nRet,// number of bytes returned
&PollingOverlap,// pointer to structure needed for overlapped I/O
NULL);
WaitForSingleObject(PollingOverlap.hEvent,INFINITE);
// if(result)
// {
offset = 0;
int rename = 0;
char oldName[260];
char newName[260];
do
{
//pNotify = (FILE_NOTIFY_INFORMATION*)((char*)buf + offset);
strcpy(filename, "");
int filenamelen = WideCharToMultiByte(CP_ACP, 0, pNotify[offset].FileName, pNotify[offset].FileNameLength/2, filename, sizeof(filename), NULL, NULL);
//filename[pNotify->FileNameLength/2] = ' ';
switch(pNotify[offset].Action)
{
case FILE_ACTION_ADDED:
qDebug() << "The FILE_ACTION_ADDED***********" << QString(filename).left(filenamelen);
emit onFileCopy(QString(filename).left(filenamelen));
break;
case FILE_ACTION_MODIFIED:
qDebug() << "The FILE_ACTION_MODIFIED" << QString(filename).left(filenamelen);
break;
case FILE_ACTION_REMOVED:
qDebug() << "The FILE_ACTION_REMOVED" << QString(filename).left(filenamelen);
emit onFileRemove(QString(filename).left(filenamelen));
break;
case FILE_ACTION_RENAMED_OLD_NAME:
qDebug() << "The FILE_ACTION_RENAMED_OLD_NAME" << QString(filename).left(filenamelen);
break;
case FILE_ACTION_RENAMED_NEW_NAME:
newDirName = QString(filename).left(filenamelen);
qDebug() << "The FILE_ACTION_RENAMED_NEW_NAME" << newDirName;
emit onDirRename(newDirName);
break;
default:
printf("\nDefault error.\n");
break;
}
//qDebug() << "pNotify->NextEntryOffset" << pNotify[offset].NextEntryOffset <<" offset "<< offset << nRet ;
offset += pNotify[offset].NextEntryOffset;
}while(pNotify[offset].NextEntryOffset); //(offset != 0)
ResetEvent(PollingOverlap.hEvent);
}
CloseHandle( DirInfo[0].hDir );
当对监视目录内的文件进行正常删除时,我无法收到通知。