文件的异步读写

文件异步读写

1: 普通的读写文件打开文件都是同步的,比如C的fopen, fclose, fread等;
2: 磁盘的访问速度远远的低于内存,所以OS要等待磁盘设备来读写。
3: 如果采用同步,那么任务将会挂机,等待磁盘读好数据好,通知OS。
4: 高性能的服务器,提高并发,读写文件都会采用异步的模式。
5: 异步的模式:

1>发出读文件的请求;
2>通完了以后通知应用程序,并处理;

win同步读

1: 同步打开一个文件:

HANDLE hFile = CreateFile(路径, GENERIC_READ, 0,
	NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL);
GENERIC_READ只读的方式;

2: 同步读一个文件:ReadFile(hFile, buf, max_len,&dwRead,&overlap);
3: 关闭一个文件: CloseHandle(hFile);

Win异步读

1: 异步打开一个文件:

HANDLE hFile = CreateFile(路径, GENERIC_READ, 0,
NULL,OPEN_EXISTING, 
FILE_FLAG_OVERLAPPED|FILE_ATTRIBUTE_NORMAL,NULL);
FILE_FLAG_OVERLAPPED: 异步的方式打开文件的标志, GENERIC_READ只读的方式;

2: 创建一个OVERLAPPED对象,传递给OS,携带一个事件,当读完成后,触发事件;

OVERLAPPED overlap;
overlap.Offset = 0; //文件开始读写的偏移位置,该偏移位置从文件头开始算起
overlap.OffsetHigh =0;  //64位的文件偏移位置中较高的32位
overlap.hEvent = hEvent;

3: 读文件: ReadFile(hFile, buf, max_len,&dwRead,&overlap);
4:将事件加入等待集合来等待完成。

WaitForSingleObject/WaitForMultipleObjects,GetLastError获取错误信息

5: 关闭一个文件: CloseHandle(hFile);

同步与异步的区别

1: 都是要等,一个是在用户面来控制,一个是在内核控制;
2: 在内核等的同步,灵活度不够, 真只能等一个,但是简单;
3: 用户来控制等待,可以同时等多个处理;
4: 异步:可以同时处理多个请求,发出请求后,等待所有的这些事件,随着他们的结束再处理,继续等待;

同时等待多个句柄

1:

DWORD WaitForMultipleObjects(  
  DWORD nCount,             //  指定列表中的句柄数量  最大值为MAXIMUM_WAIT_OBJECTS  
  CONST HANDLE *lpHandles,  // 句柄数组的指针  
  BOOL fWaitAll,            // 等待的类型,如果为TRUE,表示除非对象都发出信号,否则就一直等待下去;如果FALSE,表示任何对象发出信号即可
  DWORD dwMilliseconds      // 指定要等候的毫秒数。如设为零,表示立即返回。如指定常数INFINITE,则可根据实际情况无限等待下去  
);  

2: 返回值:

WAIT_TIMEOUT: 对象保持未发信号的状态,但规定的等待超时时间已经超过
WAIT_OBJECT_0: 所有对象都发出了信号;
WAIT_FAILED: 执行失败,可以通过GetLastError获取错误信息;
nIndex : WAIT_OBJECT_0 + 5,5个对象发出了事件;

demo

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <Windows.h>

int main(int argc, char** argv)
{
#if 0
	//同步
	char buf[1024];
	DWORD readed = 1024;
	int ret;
	//HANDLE 句柄: 当前对象的唯一标识
	HANDLE hfile = INVALID_HANDLE_VALUE; // 打开失败或返回失败会INVALID_HANDLE_VALUE
	hfile = CreateFile(L"bin//in.txt", GENERIC_READ, 0, NULL,
		OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // OPEN_EXISTING 打开已经存在文件
	if (hfile == INVALID_HANDLE_VALUE)
	{
		printf("open error\n");
		goto failed;
	}


	ret = ReadFile(hfile, buf, 1024, &readed, NULL);
	if (ret == 0)
	{
		goto failed;
	}
	buf[readed] = 0;
	printf("%s\n", buf);
#else
	//异步 FILE_FLAG_OVERLAPPED 模式
	char buf[1024];
	DWORD readed = 1024;
	OVERLAPPED overlap;
	memset(&overlap, 0, sizeof(overlap));
	HANDLE hevent = CreateEvent(NULL, false, false, NULL);

	HANDLE hfile = INVALID_HANDLE_VALUE; // 打开失败或返回失败会INVALID_HANDLE_VALUE
	hfile = CreateFile(L"bin//in.txt", GENERIC_READ, 0, NULL,
		OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_ATTRIBUTE_NORMAL, NULL); // OPEN_EXISTING 打开已经存在文件
	if (hfile == INVALID_HANDLE_VALUE)
	{
		printf("open error\n");
		goto failed;
	}

	//读的时候, 发送请求, 准备一个OVERLAPPED对象
	// 传给OS, 等OS读完以后, 会通过OVERLAPPED给我们发送一个事件
	overlap.hEvent = hevent;
	overlap.Offset = 0;  // 从第0个字符开始读起

	// 马上返回, IO挂起, 没有读到数据,ERROR_IO_PENDING状态
	ReadFile(hfile, buf, 1024, &readed, &overlap);
	if (GetLastError() == ERROR_IO_PENDING)
	{
		WaitForSingleObject(hevent, INFINITE); //一直等待
		readed = overlap.InternalHigh;  //读到了一个字节的数据;
		buf[readed] = 0;
		printf("async %s\n", buf);
	}


#endif

	CloseHandle(hfile);
failed:
	return 0;
}
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值