【发布时间】:2017-12-22 15:05:17
【问题描述】:
在我的工作线程中,我需要能够在用户输入时停止长文件操作。我目前的方法是在一个小缓冲区上重复调用ReadFile,然后在每次迭代后调用回调函数。像这样的:
//Error checks are omitted for brevity
for(;;)
{
::ReadFile(hFile, SmallBuffer, nSizeOfSmallBuffer, nBytesRead);
if(!pfnCallbackProc())
{
//Abort
break;
}
}
BOOL callbackProc()
{
return ::WaitForSingleObject(hStopEvent, 0) == WAIT_OBJECT_0;
}
此方法有效。但是,当我进行基准测试以查看它对一个简单调用的运行速度有多慢时:
::ReadFile(hFile, FullBuffer, nSizeOfFullBuffer, nBytesRead);
SSD(随机存取磁盘)上的差异并不大,但当我从旋转驱动器读取大文件时,差异会变得非常明显。例如,使用单个ReadFile 读取一个 4GB 文件大约需要 32 秒,使用我的方法和上面的回调大约需要 46 秒。 (据我所知,由于在旋转磁盘上反复调用 ReadFile,会导致更大的延迟。)
所以我想知道是否有更有效的方法来做到这一点?
【问题讨论】:
-
当您标记 winapi 时,请阅读 MSDN 上的 I/O Completion Ports msdn.microsoft.com/en-us/library/windows/desktop/… 也重叠 IO:msdn.microsoft.com/en-us/library/windows/desktop/…
-
唯一的办法就是降低循环的迭代量。一种方法是增加您读取的缓冲区大小。您只需要尝试多种不同的读取缓冲区大小,这样您就可以获得可接受的性能,同时仍然能够满足程序的要求(例如能够在足够短的时间内取消读取)。跨度>
-
在您的程序运行期间(不是设计时,但我的意思是在您实际发布的应用程序中)花哨并对其进行测量,并将尺寸调整为尽可能大,但仍然具有响应性。跨度>
-
如果您想停止阅读,只需在文件中调用
CancelIoEx -
什么是nSizeOfSmallBuffer
标签: c++ winapi readfile hard-drive