Dark_dance

取次花丛懒回首,半缘修道半缘君

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

1、Overlapped I/O 的含义

Overlapped I/O 是WIN32的一项技术,可以让操作系统进行I/O操作而不阻塞的程序执行,并且I/O操作完成时通知程序。

事实上Overlapped I/O操作系统最终是以线程的方式实现。

2、使用Overlapped I/O

Windows中通过CreateFile来打开各种资源。如:文件、串口、并口、Name pipes、Console等等。

1: HANDLE WINAPI CreateFile(
2: __in LPCTSTR lpFileName, //资源名称
3: __in DWORD dwDesiredAccess, //存取模式
4: __in DWORD dwShareMode, //共享模式
5: __in_opt LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性结构
6: __in DWORD dwCreationDisposition,//如何产生
7: __in DWORD dwFlagsAndAttributes, //资源属性
8: __in_opt HANDLE hTemplateFile //零时文件,将拥有全部属性的拷贝
9: );
其第6个参数指定为FILE_FLAG_OVERLAPPED,就是准备使用overlapped的方式构造或打开文件;

如果采用 overlapped,那么ReadFile()、WriteFile()的第5个参数必须提供一个指针,指向一个OVERLAPPED结构。 OVERLAPPED用于记录了当前正在操作的文件一些相关信息。

1: BOOL WINAPI ReadFile(
2: __in HANDLE hFile, //资源句柄
3: __out LPVOID lpBuffer, //输出缓冲区指针
4: __in DWORD nNumberOfBytesToRead, //输出字节数
5: __out_opt LPDWORD lpNumberOfBytesRead, //实际读取的字节个数的地址
6: __inout_opt LPOVERLAPPED lpOverlapped //指向Overlapped info
7: );
8: BOOL WINAPI WriteFile(
9: __in HANDLE hFile, //资源指针
10: __in LPCVOID lpBuffer, //写入数据缓冲区
11: __in DWORD nNumberOfBytesToWrite, //写入字节数
12: __out_opt LPDWORD lpNumberOfBytesWritten,//实际写入字节数
13: __inout_opt LPOVERLAPPED lpOverlapped //指向Overlapped info
14: );
Overlapped 结构

1: typedef struct _OVERLAPPED
2: {
3: ULONG_PTR Internal;
4: ULONG_PTR InternalHigh;
5: union {
6: struct {
7: DWORD Offset;
8: DWORD OffsetHigh;
9: };
10: PVOID Pointer;
11: };
12: HANDLE hEvent;
13: } OVERLAPPED, *LPOVERLAPPED;
结构字段含义

Internal:保留为系统使用。当GetOverlappedResult返回False时,且用GetLastError返回不是ERROR_IO_PENDING时,该字段为一个视系统而定的状态。

InternalHigh:保留为系统使用。当GetOverlappedResult为TRUE时,该字段为被传输数据长度。

Offset:当目标设备为文件时该字段有效,其他时候必须为0;表示文件中被传输数据的偏移位置(从文件头开始计算)。

OffsetHigh:64位文件偏移中的高32位。当目标设备为文件时有效。其他时候必须为0。

Pointer:保留为系统时候。

hEvent:一个手动复位的事件句柄,当Overlapper I/O完成时,被触发。

1: BOOL WINAPI GetOverlappedResult(
2: __in HANDLE hFile, //资源句柄
3: __in LPOVERLAPPED lpOverlapped, //Overlapped指针
4: __out LPDWORD lpNumberOfBytesTransferred, //真正被传输的字节数
5: __in BOOL bWait //是否需要等等I/O完成
6: );
示例:

1: #include <Windows.h>
2: #include <stdio.h>
3:
4: int main()
5: {
6: BOOL bRet;
7: HANDLE hFile = NULL;
8: OVERLAPPED overlapped;
9: LPCTSTR szPath = TEXT("H:\\Resource.rar");
10: unsigned char buf[1024*100];
11: DWORD nRead = 0;
12: /*以OVERLAPPED方式打开一个文件*/
13: hFile = ::CreateFile(szPath,
14: GENERIC_ALL,
15: FILE_SHARE_READ | FILE_SHARE_WRITE,
16: NULL,
17: OPEN_EXISTING,
18: FILE_FLAG_OVERLAPPED,
19: NULL
20: );
21: if (hFile != INVALID_HANDLE_VALUE)
22: {
23: memset(&overlapped,0x00,sizeof(overlapped));
24: memset(buf,0x00,sizeof(buf));
25: overlapped.Offset = 0;
26:
27: bRet = ::ReadFile(hFile,
28: buf,
29: 1024*10,
30: &nRead,
31: &overlapped
32: );
33: if (bRet)
34: {
35: for (DWORD i = 0;i < nRead;i++)
36: {
37: printf("%02X ",buf[i]);
38: if ((i + 1) % 16 == 0)
39: {
40: printf("\n");
41: }
42: }
43: printf("\n");
44: }
45: else
46: {
47: DWORD err = GetLastError();
48: if (err == ERROR_IO_PENDING)
49: {
50: bRet = GetOverlappedResult(hFile,&overlapped,&nRead,TRUE);
51: if (bRet)
52: {
53: for (DWORD i = 0;i < nRead;i++)
54: {
55: printf("%02X ",buf[i]);
56: }
57: printf("\n");
58: }
59: else
60: {
61: printf("Error Code : %d\n",GetLastError());
62: }
63: }
64: else
65: {
66: printf("Error Code : %d\n",err);


posted on 2011-12-04 19:56  流沙-  阅读(439)  评论(0编辑  收藏  举报