等待句柄
#include <stdio.h>
#include <windows.h>
// 1. 如果想要对一个文件进行异步操作,就必须在打开文件时指定 FILE_FLAG_OVERLAPPED
// 2. 每次 [投递] 一个异步 IO 操作,都需要提供一个 OVERLAPPED 结构体
// 3. 当执行的是异步 IO 操作的时候,文件指针就没有作用了,需要使用 OVERLAPPED 设置
// 4. ReadFile 和 WriteFile 的第 4 个参数,实际操作数量就没有意义了
// 5. 当使用 FILE_FLAG_OVERLAPPED 打开一个文件时,句柄就拥有了信号状态
// - 当 IO 操作完成时,处于有信号状态,使用 WaitForSingleObject 进行判断
int main()
{
// 1. 以重叠 IO 的方式打开一个文件
HANDLE FileHandle = CreateFile(L"test.txt", GENERIC_ALL,
NULL, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
// 2. 创建并初始化一个重叠 IO 结构体,每次请求都要有独立的结构体
OVERLAPPED OverLapped = { 0 };
// 2.1 设置文件操作的偏移位置为 [3]
OverLapped.Offset = 3;
// 3. 投递一个 IO 请求
CHAR Buffer[10] = { 0 };
ReadFile(FileHandle, Buffer, 3, NULL, &OverLapped);
// 4. 等待文件句柄,如果有信号就是说明 IO 请求完成了
WaitForSingleObject(FileHandle, INFINITE);
// 5. 获取异步 IO 操作的操作状态
DWORD RealOperator = 0;
BOOL Result = GetOverlappedResult(
FileHandle, // 执行 IO 的句柄
&OverLapped, // 对应的重叠 IO 结构体
&RealOperator, // 实际读写的数量
FALSE); // 是否等待 IO 操作执行结束
// 最后一个参数表示是都等待 IO 操作完成,如果之前调用了
// 等待函数,那么这个字段就没有意义
// 缺点:能够被等待的对象只有一个文件句柄,如果投递了
// 多个IO操作,那么,并不能区分实际完成的是哪一个。
return 0;
}
// typedef struct _OVERLAPPED {
// // 当前绑定的异步 IO 操作是否成功完成
// ULONG_PTR Internal;
//
// // 当前的 IO 操作成功读取或者写入的数量
// ULONG_PTR InternalHigh;
//
// // 执行异步 IO 时文件指针所在的位置
// union {
// struct {
// DWORD Offset;
// DWORD OffsetHigh;
// } DUMMYSTRUCTNAME;
// PVOID Pointer;
// } DUMMYUNIONNAME;
//
// // 事件对象,在某些时候会用到,可能充当其它角色
// HANDLE hEvent;
// } OVERLAPPED, * LPOVERLAPPED;