我设法同步使用ReadDirectoryChangesW
,但当我尝试使用完成端口时,ReadDirectoryChangesW
始终返回ERROR_INVALID_PARAMETER
。我想我的代码中应该有一些明显的错误,但我无法理解它。
我的代码基于How to use ReadDirectoryChangesW() method with completion routine?
const wchar_t *directory = L"X:\\X";
HANDLE h = CreateFile(
directory,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS|FILE_FLAG_OVERLAPPED, NULL);
if (h==INVALID_HANDLE_VALUE) return;
HANDLE p = CreateIoCompletionPort(h,0,0,1);
if (p==NULL) {CloseHandle(h); return;}
DWORD *buffer =new DWORD[4096];
DWORD bytesReturned;
DWORD notifyFilter = FILE_NOTIFY_CHANGE_FILE_NAME
| FILE_NOTIFY_CHANGE_DIR_NAME
| FILE_NOTIFY_CHANGE_SIZE
| FILE_NOTIFY_CHANGE_LAST_WRITE;
while (true) {
OVERLAPPED overlapped;
memset(&overlapped,0,sizeof(overlapped));
BOOL success = ReadDirectoryChangesW(h,
&buffer[0],
4096*sizeof(DWORD),
FALSE, notifyFilter,
NULL, //&bytesReturned,
&overlapped,myFileIOCompletionRoutine);
if (!success) {
//always ERROR_INVALID_PARAMETER
CloseHandle(h);
CloseHandle(p);
return;
}
}
答案 0 :(得分:1)
正如Hans Passant所提醒的,the documentation已经说过,如果目录与完成端口相关联,则不得使用 。在这种情况下,我通过等待完成端口解决了问题,即ReadDirectoryChangesW(...,&overlapped,0);
完整代码如下。
while (true) {
OVERLAPPED overlapped;
memset(&overlapped,0,sizeof(overlapped));
BOOL success = ReadDirectoryChangesW(h,
&buffer[0],
4096*sizeof(DWORD),
FALSE, notifyFilter, 0, &overlapped,0);
if (!success) {
if (GetLastError()==ERROR_INVALID_HANDLE) {
//asynchronously closed by cancel
CloseHandle(p); //close completion port
return 0;
} else {
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return 1;
}
}
DWORD di;
LPOVERLAPPED lpOverlapped;
if (!GetQueuedCompletionStatus(p,&bytesReturned,&di,&lpOverlapped,1000)) {
int ret;
if (GetLastError()==WAIT_TIMEOUT) {
if (GetFileAttributes(directory)!=INVALID_FILE_ATTRIBUTES) {
continue; //timeout
} else {
//directory has been deleted or renamed
ret=0;
}
} else {
//other failure
ret=1;
}
CloseHandle(h); //close directory handle
CloseHandle(p); //close completion port
return ret;
}
char* ptr = (char*)&buffer[0];
char* end = ptr+bytesReturned;
while (ptr<end) {
FILE_NOTIFY_INFORMATION *info = (FILE_NOTIFY_INFORMATION*) ptr;
//process FILE_NOTIFY_INFORMATION
ptr+=info->NextEntryOffset;
if (!info->NextEntryOffset) break;
}
}