#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;