ReadFile功能

https://docs.microsoft.com/zh-cn/windows/win32/api/ioapiset/nf-ioapiset-getoverlappedresult
8分钟阅读时长
从指定的文件或输入/输出(I / O)设备读取数据。如果设备支持,则在文件指针指定的位置进行读取。

此功能设计用于同步和异步操作。有关专门为异步操作设计的类似功能,请参见ReadFileEx。

BOOL ReadFile(
  HANDLE       hFile,
  LPVOID       lpBuffer,
  DWORD        nNumberOfBytesToRead,
  LPDWORD      lpNumberOfBytesRead,
  LPOVERLAPPED lpOverlapped
);

参量

hFile

设备的句柄(例如,文件,文件流,物理磁盘,卷,控制台缓冲区,磁带驱动器,套接字,通信资源,邮槽或管道)。

该HFILE参数必须已经具有读取权限创建。有关更多信息,请参见通用访问权限和 文件安全性和访问权限。

对于异步读取操作,hFile可以是CreateFile函数使用FILE_FLAG_OVERLAPPED标志 打开的任何句柄 ,或者是socket或 accept函数返回的套接字句柄 。

lpBuffer

指向缓冲区的指针,该缓冲区接收从文件或设备读取的数据。

该缓冲区必须在读取操作期间保持有效。在读取操作完成之前,调用者不得使用此缓冲区。

nNumberOfBytesToRead

读取的最大字节数。

lpNumberOfBytesRead

指向变量的指针,该变量接收使用同步hFile参数时读取的字节 数。在执行任何工作或错误检查之前,ReadFile将此值设置为零。如果这是异步操作,请对该参数使用NULL以避免潜在的错误结果。

仅当lpOverlapped 参数不为NULL时,此参数才能为NULL。

有关更多信息,请参见“备注”部分。

lpOverlapped

如果使用FILE_FLAG_OVERLAPPED打开hFile参数, 则需要指向OVERLAPPED结构的指针,否则可以为NULL。

如果使用FILE_FLAG_OVERLAPPED打开hFile,则 lpOverlapped参数必须指向有效且唯一的OVERLAPPED结构,否则该函数可能会错误地报告读取操作已完成。

对于支持字节偏移量的hFile,如果使用此参数,则必须指定一个字节偏移量,从该位置开始从文件或设备读取。通过设置OVERLAPPED结构的Offset和OffsetHigh成员 来指定此偏移量 。对于不支持字节偏移量的 hFile,将忽略Offset和 OffsetHigh。

有关lpOverlapped和 FILE_FLAG_OVERLAPPED的不同组合的更多信息,请参见“备注”部分和“ 同步和文件位置”部分。

返回值
如果函数成功,则返回值为非零(TRUE)。

如果函数失败或异步完成,则返回值为零(FALSE)。若要获取扩展的错误信息,请调用 GetLastError函数。

注意 该GetLastError函数代码 ERROR_IO_PENDING还不是一个失败者; 它指定读取操作正在异步完成中。有关更多信息,请参见备注。

备注
所述的ReadFile当以下条件之一发生功能返回:

读取请求的字节数。
写入操作在管道的写入端完成。
正在使用异步句柄,并且读取是异步发生的。
发生错误。
每当有太多未完成的异步I / O请求时,ReadFile函数可能会因ERROR_INVALID_USER_BUFFER或ERROR_NOT_ENOUGH_MEMORY而失败 。

要取消所有暂挂的异步I / O操作,请使用以下任一方法:

CancelIo —此函数仅取消由调用线程针对指定的文件句柄发出的操作。
CancelIoEx-此函数取消线程为指定的文件句柄发出的所有操作。
使用CancelSynchronousIo取消挂起的同步I / O操作。

取消的I / O操作完成,错误为ERROR_OPERATION_ABORTED。

该ReadFile的功能可能会失败, ERROR_NOT_ENOUGH_QUOTA,这意味着调用进程的缓冲区不能页面锁定。有关更多信息,请参见 SetProcessWorkingSetSize。

如果文件的一部分被另一个进程锁定,并且读取操作与锁定的部分重叠,则此功能将失败。

在读取操作使用缓冲区的同时访问输入缓冲区可能会导致读入该缓冲区的数据损坏。在读取操作完成之前,应用程序不得读取,写入,重新分配或释放读取操作正在使用的输入缓冲区。使用异步文件句柄时,这可能尤其成问题。有关同步文件句柄和异步文件句柄的其他信息,可以在“ 同步和文件位置”部分以及“ CreateFile”参考主题中找到。

通过使用带有控制台输入句柄的ReadFile,可以从控制台输入缓冲区读取字符 。控制台模式确定ReadFile函数的确切行为。默认情况下,控制台模式为ENABLE_LINE_INPUT,它指示 ReadFile应该读取直到到达回车符为止。如果按Ctrl + C,则调用成功,但是GetLastError返回 ERROR_OPERATION_ABORTED。有关更多信息,请参见 CreateFile。

从通信设备读取时,ReadFile的行为 由设置和使用SetCommTimeouts和 GetCommTimeouts函数检索的当前通信超时确定。如果您无法设置超时值,则可能会发生不可预测的结果。有关通信超时的更多信息,请参见 COMMTIMEOUTS。

如果ReadFile尝试从缓冲区太小的邮槽读取,则该函数返回FALSE,而 GetLastError返回 ERROR_INSUFFICIENT_BUFFER。

使用 FILE_FLAG_NO_BUFFERING标志成功使用CreateFile打开的文件有严格的要求 。有关详细信息,请参见 文件缓冲。

如果使用FILE_FLAG_OVERLAPPED打开hFile,则以下条件有效:

该lpOverlapped的参数必须指向一个有效的和独特的 OVERLAPPED结构,否则该函数可以错误地报告读操作完成。
该lpNumberOfBytesRead参数应设置为 NULL。使用 GetOverlappedResult函数获取读取的实际字节数。如果hFile参数与I / O完成端口关联,则还可以通过调用GetQueuedCompletionStatus函数来获取读取的字节数 。
同步和文件位置
如果使用FILE_FLAG_OVERLAPPED打开hFile,则它是一个异步文件句柄;否则,它是同步的。如前所述,每种情况下使用OVERLAPPED结构的规则 略有不同。
注意 如果打开文件或设备以进行异步I / O,则随后使用该句柄对诸如ReadFile之类的函数的后续调用 通常会立即返回,但在阻塞执行方面也可以同步运行。有关更多信息,请参见 http://support.microsoft.com/kb/156932。

使用异步文件句柄的注意事项:
ReadFile可能在读取操作完成之前返回。在这种情况下,ReadFile返回 FALSE,而GetLastError 函数返回ERROR_IO_PENDING,这允许调用过程在系统完成读取操作时继续进行。
该lpOverlapped的参数不能为NULL,应注意以下事实中:
尽管OVERLAPPED 结构中指定的事件是由系统自动设置和重置的,但是OVERLAPPED结构中指定的偏移量 不会自动更新。
ReadFile在开始I / O操作时将事件重置为非信号状态。
当读取操作完成时,在OVERLAPPED结构中指定的事件将设置为有信号状态;直到那个时候,读取操作才被视为未决。
由于读取操作从OVERLAPPED结构中指定的偏移量开始 ,并且 ReadFile可能在系统级读取操作完成(读取暂挂)之前返回,因此,偏移量和结构的任何其他部分都不应修改,释放,或由应用程序重用,直到发信号通知事件(即读取完成)为止。
如果在异步操作期间检测到文件结尾(EOF),则对该操作的GetOverlappedResult调用 返回FALSE,而 GetLastError返回 ERROR_HANDLE_EOF。
使用同步文件句柄的注意事项:
如果lpOverlapped为NULL,则读取操作从当前文件位置开始,并且直到完成该操作,ReadFile才返回,并且系统在ReadFile返回之前更新文件指针 。
如果lpOverlapped不为NULL,则读取操作从OVERLAPPED结构中指定的偏移量开始, 并且 ReadFile直到读取操作完成才返回。系统在ReadFile返回之前更新OVERLAPPED偏移量。
当同步读取操作到达文件末尾时, ReadFile返回TRUE并设置 *lpNumberOfBytesRead为零。
欲了解更多信息,请参阅的CreateFile和 同步和异步I / O。
管子
如果正在使用匿名管道,并且已关闭写入句柄,则当 ReadFile尝试使用管道的相应读取句柄进行读取时,该函数返回FALSE,而 GetLastError返回 ERROR_BROKEN_PIPE。
如果正在消息模式下读取命名管道,并且下一条消息的长度大于nNumberOfBytesToRead参数指定的长度 ,则 ReadFile返回FALSE,而 GetLastError返回 ERROR_MORE_DATA。后续的ReadFile或 PeekNamedPipe函数可以读取消息的其余部分 。

如果ReadFile在管道上返回TRUE时lpNumberOfBytesRead参数为零 ,则管道的另一端称为WriteFile函数,且 nNumberOfBytesToWrite设置为零。

有关管道的更多信息,请参见管道。

交易业务
如果文件句柄绑定了事务,则该函数从文件的事务视图返回数据。事务处理的读取句柄保证在该句柄期间显示文件的相同视图。有关更多信息,请参见 关于事务性NTFS。
在Windows 8和Windows Server 2012中,以下技术支持此功能。

技术 支持的
服务器消息块(SMB)3.0协议 是
SMB 3.0透明故障转移(TFO) 是
具有横向扩展文件共享(SO)的SMB 3.0 是
群集共享卷文件系统(CsvFS) 是
弹性文件系统(ReFS) 是

例子
有关显示如何测试文件结尾的代码示例,请参见测试文件 结尾。有关其他示例,请参见 创建和使用临时文件以及 打开文件进行读取或写入。

你可能感兴趣的:(编程高级进阶)