程序员思维过程:确定将ReadFile与Windows API一起使用时要读取的最大字节数



我需要调用Windows API的ReadFile函数:

BOOL WINAPI ReadFile(
  _In_        HANDLE       hFile,
  _Out_       LPVOID       lpBuffer,
  _In_        DWORD        nNumberOfBytesToRead,
  _Out_opt_   LPDWORD      lpNumberOfBytesRead,
  _Inout_opt_ LPOVERLAPPED lpOverlapped
);

我感兴趣的论点是第三个:

nNumberOfBytesToRead [in]

要读取的最大字节数。

我对放在那里的

"神奇数字"不太感兴趣,而是经验丰富的程序员确定要放在那里的数字的过程,最好是按编号的步骤。

还要记住,我正在用汇编程序编写程序,所以我从这个角度对思考过程更感兴趣。


  • https://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx

这需要对Windows和硬件都有充分的了解。但是,总的来说,这里有一些可能的方向:

  • 写是缓冲的还是无缓冲的?如果未缓冲,那么您甚至可能无法选择大小,但必须遵循缓冲区大小和对齐方式的严格规则。
  • 通常,您希望让操作系统处理尽可能多的工作,因为它比您在用户空间中更了解存储设备本身及其各种用户。因此,如果可能的话,您可能希望一次获取整个内容(请参阅下面的要点)。
  • 如果事实证明这还不够好,您可以尝试通过玩弄各种大小来超越它,以解决您可能能够使用当前缓冲区的情况,由于某种原因,操作系统并不总是用于不同的请求。
  • 否则,您可能会使用介于磁盘扇区大小和页面大小倍数之间的任何大小,因为这些大小很可能已经缓存在某个位置,并且还直接映射到实际的硬件请求。
  • 除了性能之外,还有一个问题是在任何给定时间,您都可以在进程内存中存储多少。
  • 还有一个问题是发送大型请求,这可能会阻止其他进程有机会进入那里并在两者之间获取一些数据——如果操作系统还没有以某种方式解决这个问题。
  • 还有一种可能性是,通过请求太大的块,操作系统可能会推迟您的请求,直到其他进程获得其不起眼的块。另一方面,如果是相交的地址,它实际上可能首先提供您的地址,以便从缓存中提供其他地址。

一般来说,你可能想玩一玩,直到你得到足够好的东西。

该参数表仅用于保护您免受缓冲区溢出的影响,因此您当然必须输入为此目的分配的缓冲区的大小。除此之外,您应该只读取您对此确切时间感兴趣的字节数。现代操作系统将始终使用页面缓存,并且对文件的任何后续访问都将与访问 RAM 一样快。如果需要整个文件,您还可以强制操作系统事先缓存文件。
编辑:我的经验与Yam Marcovic和其他人的建议背道而驰。将文件缓存和分块读取到理想大小正是操作系统要做的事情。不要自以为是地超越它,只阅读你需要的东西。

最新更新