异步过程解读
为什么要采用异步读写的方式:
磁盘的访问速度远远的低于内存的速度,所以OS要等待磁盘设备读写结果
如果采用同步,那么任务将会被挂起,等待磁盘读好数据,通知OS,然后唤醒
高性能的服务器,为了提高并发,读写文件都会采用异步的模式
异步读写的过程:

这样App层并不会被挂起,可以接着处理其他的业务
项目约束
- 目录层级结构

src 存放项目代码
bin 存放待读取的文件
- 修改工作目录

选择bin文件夹
Windows 同步读取实现
- 同步打开一个文件
HANDLE WINAPI CreateFile(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
这里需要注意的是,如果当前你的编译环境定义了UNICODE的宏,你需要在lpFileName前面加上L,代表此段字符串为Unicode编码
- 同步读取一个文件
BOOL WINAPI ReadFile(hFile, buf, max_len,&dwRead,&overlap);
- 关闭文件
BOOL WINAPI CloseHandle(HANDLE hObject);
- 代码实现
HANDLE hfile = INVALID_HANDLE_VALUE;
hfile = CreateFile("in.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
#pragma region 同步读取
if (hfile == INVALID_HANDLE_VALUE) {
printf("open error.\n");
goto failed;
}
char buf[1024];
int readed;
ReadFile(hfile, buf, 1024, &readed, NULL);
buf[readed] = 0; // 文件结束标志位
printf("%s\n", buf);
CloseHandle(hfile);
#pragma endregion
- 执行结果

Windows 异步读取
- 异步打开一个文件
HANDLE hFile = CreateFile(路径, GENERIC_READ, 0,NULL,OPEN_EXISTING, FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL);
这里于同步不同的地方是,
dwFlagsAndAttributes
使用的是FILE_FLAG_OVERLAPPED
|FILE_ATTRIBUTE_NORMAL

- 创建一个OVERLAPPED对象,传递给OS,并携带一个事件,当读取完成后,触发此事件
OVERLAPPED overlap;
overlap.Offset = 0;
overlap.hEvent = hEvent;
- 读文件
BOOL WINAPI ReadFile(hFile, buf, max_len,&dwRead,&overlap);
- 将事件加入等待集合来等待完成
DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
如果这里需要等待多个需要使用
WaitForMultipleObjects
API
- 关闭一个文件
BOOL WINAPI CloseHandle(HANDLE hObject);
- 代码实现
# pragma region 异步读取
hfile = CreateFile("in.txt", GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, NULL);
if (hfile == INVALID_HANDLE_VALUE) {
printf("open error.\n");
goto failed;
}
OVERLAPPED ov;
HANDLE hevent = CreateEvent(NULL, FALSE, FALSE, NULL);
memset(&ov, 0, sizeof(ov));
ov.hEvent = hevent;
ov.Offset = 0;
ReadFile(hfile, buf, 1024, &readed, &ov);
if (GetLastError() == ERROR_IO_PENDING) {
WaitForSingleObject(hevent, INFINITE);
readed = ov.InternalHigh;
buf[readed];
printf("%s\n", buf);
CloseHandle(hfile);
} else {
CloseHandle(hfile);
}
#pragma endregion
- 执行结果

Comments | NOTHING