Overlapped I/O 学习

86 篇文章 0 订阅
48 篇文章 0 订阅

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);
  67:             }
  68:         }
  69:         CloseHandle(hFile);
  70:     }
  71:     else
  72:     {
  73:         printf("Error Code : %d\n",GetLastError());    
  74:     }    
  75:     char ch = getchar();
  76:     return 0;
  77: }

 

获取更多帮主请关注小程序

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值