Win32 API 中的 ReadFile 函数

Posted

技术标签:

【中文标题】Win32 API 中的 ReadFile 函数【英文标题】:ReadFile function from Win32 API 【发布时间】:2012-09-21 05:32:00 【问题描述】:

我从 Win32 API 收到了两个关于 ReadFile 函数的问题。首先,鉴于

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

第三个和第四个参数是DWORD类型,最多可以容纳1^32而不溢出。这是否意味着 ReadFile 一次只能读取少于 1^32 字节数据的文件?如果这是真的,我想读取一个大于 1^32 的文件,我会将 ReadFile 放在这样的循环中

char buffer[1<<32];
while(!EOF)
  ReadFIle(filename,buffer,1^32,bytesout,NULL);
  SomeFunctionToExtractDataFromBuffer(buffer)

假设循环倾向于在每次迭代时覆盖缓冲区,为了使这种设计工作,ReadFile 需要记住文件中先前读取发生的位置,这是真的吗?或者还有其他方法可以实现这一点。非常感谢

【问题讨论】:

请修改此问题的标题,以便对本网站的未来访问者有用。否则它可能会因为过于本地化而被关闭。 没有理由假设 DWORD 的大小是 32。有很多商业应用,它更高。 【参考方案1】:

第三个和第四个参数是DWORD类型,可以容纳 最大 1^32 没有溢出。是不是意味着ReadFile只能 一次读取一个少于 1^32 字节数据的文件?

没有。这意味着它一次最多只能读取 2^32 个字节。没有人阻止您多次调用ReadFile 来读取任意数量的字节(每次读取都会推进file pointer,因此它将从上一次读取停止的位置开始读取)。

假设循环倾向于在每次迭代时覆盖缓冲区,在 为了让这个设计工作,ReadFile 需要记住在哪里 文件中发生的先前读取是真的吗?

是的,操作系统会为每个打开的文件记住这一点(参见上面的文件指针链接)。

关于这个主题,我应该提到,如果您安排 4GB 读取,那么您很可能做错了什么。无论您的数据的性质如何,您肯定可以以更小的块处理它,这将有助于避免遇到各种问题,例如可用内存。

【讨论】:

很高兴知道,他们确实应该在文档中说明这一点。实际上,我正在以小块的形式处理它,例如一次处理多个 MB。只是好奇 ReadFile 函数文件指针,如果它记得它在哪里。再次感谢

以上是关于Win32 API 中的 ReadFile 函数的主要内容,如果未能解决你的问题,请参考以下文章

使用 ReadFile 函数从进程中读取数据

用WIN32读取文本文件

汇编中的win32 api帮助

在命名管道上选择

win32 API 笔记1

ring0 ShadowSSDTHook