C++ 文件\u标志\u无\u缓冲与重叠I/O-字节读取为零
在使用带有重叠I/O的标志文件\u flag\u NO\u缓冲时,我观察到一种奇怪的行为。 我调用了一系列ReadFile()函数调用,稍后使用GetOverlappedResult()查询它们的状态 我所说的奇怪行为是,尽管文件句柄是好的,并且ReadFile()调用返回时没有任何错误(除了预期的error\u IO\u PENDING),但对于某些文件,从GetOverlappedResult()调用返回的“bytes read”值为零,并且每次我运行代码时,它都是一组不同的文件。 如果我删除文件标志\u NO\u缓冲,事情就会开始正常工作,没有字节读取值为零。 下面是我如何使用文件\标志\无\缓冲实现重叠I/O代码的C++ 文件\u标志\u无\u缓冲与重叠I/O-字节读取为零,c++,windows,winapi,file-io,C++,Windows,Winapi,File Io,在使用带有重叠I/O的标志文件\u flag\u NO\u缓冲时,我观察到一种奇怪的行为。 我调用了一系列ReadFile()函数调用,稍后使用GetOverlappedResult()查询它们的状态 我所说的奇怪行为是,尽管文件句柄是好的,并且ReadFile()调用返回时没有任何错误(除了预期的error\u IO\u PENDING),但对于某些文件,从GetOverlappedResult()调用返回的“bytes read”值为零,并且每次我运行代码时,它都是一组不同的文件。 如果我删
long overlappedIO(std::vector<std::string> &filePathNameVectorRef)
{
long totalBytesRead = 0;
DWORD bytesRead = 0;
DWORD bytesToRead = 0;
std::map<HANDLE, OVERLAPPED> handleMap;
HANDLE handle = INVALID_HANDLE_VALUE;
DWORD accessMode = GENERIC_READ;
DWORD shareMode = 0;
DWORD createDisposition = OPEN_EXISTING;
DWORD flags = FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING;
DWORD fileSize;
LARGE_INTEGER li;
char * buffer;
BOOL success = false;
for(unsigned int i=0; i<filePathNameVectorRef.size(); i++)
{
const char* filePathName = filePathNameVectorRef[i].c_str();
handle = CreateFile(filePathName, accessMode, shareMode, NULL, createDisposition, flags, NULL);
if(handle == INVALID_HANDLE_VALUE){
fprintf(stdout, "\n Error occured: %d", GetLastError());
fprintf(stdout," getting handle: %s",filePathName);
continue;
}
GetFileSizeEx(handle, &li);
fileSize = (DWORD)li.QuadPart;
bytesToRead = (fileSize/g_bytesPerPhysicalSector)*g_bytesPerPhysicalSector;
buffer = static_cast<char *>(VirtualAlloc(0, bytesToRead, MEM_COMMIT, PAGE_READWRITE));
OVERLAPPED overlapped;
ZeroMemory(&overlapped, sizeof(overlapped));
OVERLAPPED * lpOverlapped = &overlapped;
success = ReadFile(handle, buffer, bytesToRead, &bytesRead, lpOverlapped);
if(!success && GetLastError() != ERROR_IO_PENDING){
fprintf(stdout, "\n Error occured: %d", GetLastError());
fprintf(stdout, "\n reading file %s",filePathName);
CloseHandle(handle);
continue;
}
else
handleMap[handle] = overlapped;
}
// Status check and bytes Read value
for(std::map<HANDLE, OVERLAPPED>::iterator iter = handleMap.begin(); iter != handleMap.end(); iter++)
{
HANDLE handle = iter->first;
OVERLAPPED * overlappedPtr = &(iter->second);
success = GetOverlappedResult(handle, overlappedPtr, &bytesRead, TRUE);
if(success)
{
/* bytesRead value in some cases is unexpectedly zero */
/* no file is of size zero or lesser than 512 bytes(physical volume sector size) */
totalBytesRead += bytesRead;
CloseHandle(handle);
}
}
return totalBytesRead;
}
long-overlappedIO(std::vector和filepathname-vectoref)
{
长totalBytesRead=0;
DWORD字节读=0;
DWORD bytesToRead=0;
地图处理图;
句柄=无效的句柄值;
DWORD ACCESS MODE=通用读取;
DWORD shareMode=0;
DWORD createDisposition=打开_现有;
DWORD标志=文件标志重叠|文件标志|无缓冲;
DWORD文件大小;
大整数李;
字符*缓冲区;
布尔成功=假;
对于(无符号整数i=0;i第一;
重叠*重叠PTR=&(iter->秒);
success=GetOverlappedResult(句柄、overlappedPtr和字节读取,TRUE);
如果(成功)
{
/*在某些情况下,字节读取值意外为零*/
/*没有大小为零或小于512字节(物理卷扇区大小)的文件*/
totalBytesRead+=字节读取;
关闭手柄(手柄);
}
}
返回totalBytesRead;
}
如果没有FILE_FLAG_NO_缓冲,totalBytesRead值为57 MB。如果有此标志,totalBytesRead值远低于57 MB,并且每次运行2 MB到15 MB的代码时都会不断变化。当文件大小小于g_bytesPerPhysicalSector时,您对bytesToRead的计算结果将为0。因此对于小型files您请求的是0个字节。您对重叠结构的处理方法是错误的。您正在传递超出范围的堆栈变量的地址。请将映射更改为保留指向重叠结构的指针,并将其分配到堆上。此外,第一个ReadFile()的第四个参数对于重叠的I/O调用应该为NULL。它没有超出范围。但它肯定是错误的,每个ReadFile()都是将使用相同的I/O。这不起作用。这是否真的能改善任何东西也相当值得怀疑,重叠I/O只有在不等待它完成的情况下才有意义。文件系统是否能利用多个重叠是一个很长的问题。