006 异步IO操作

# 异步IO操作

  CreateFile 使用

    VS2015 新建win32 控制台应用程序 WindowsFileDemo

      win32控制台写窗口程序

    需要加入头文件 #include <fileAPI.h> 就可以来使用CreateFile

      分别有 CreateFileA  CreateFileW 窄字节 宽字节

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

    //第一个参数 LPCTSTR lpFileName            文件名

    //第二个参数 DWORD dwDesiredAccess           访问权限        

        GENERIC_ALL              所有权限  需要管理员权限 否则可能打开失败
        GENERIC_EXECUTE           文件是否存在
        GENERIC_READ             读
        GENERIC_WRITE             写
        GENERIC_READ | GENERIC_WRITE         组合

    //第三个参数 DWORD dwShareMode                    打开后是否共享 不需要共享的话就写入0

        0

        FILE_SHARE_DELETE

        FILE_SHARE_READ

        FILE_SHARE_WRITE

    //第四个参数 lpSecurityAttributes     一般填写nullpte

        用来设定一个指向包含两个不同但相关的数据成员:一个可选的安全描述符和一个布尔值来决定是否由子进程返回的句柄可以被继承。

    //第五个参数 DWORD dwCreationDisposition   打开方式      

        CREATE_NEW 创建文件;如文件存在则会出错
        CREATE_ALWAYS 创建文件,会改写前一个文件
        OPEN_EXISTING 文件必须已经存在。由设备提出要求
        OPEN_ALWAYS 如文件不存在则创建它
        TRUNCATE_EXISTING 将现有文件缩短为零长度

    //第六个参数 dwFlagsAndAttributesLong, 一个或多个下述常数

        FILE_ATTRIBUTE_ARCHIVE 标记归档属性

        FILE_ATTRIBUTE_COMPRESSED 将文件标记为已压缩,或者标记为文件在目录中的默认压缩方式
        FILE_ATTRIBUTE_NORMAL 默认属性
        FILE_ATTRIBUTE_HIDDEN 隐藏文件或目录
        FILE_ATTRIBUTE_READONLY 文件为只读
        FILE_ATTRIBUTE_SYSTEM 文件为系统文件
        FILE_FLAG_WRITE_THROUGH 操作系统不得推迟对文件的写操作
        FILE_FLAG_OVERLAPPED 允许对文件进行重叠操作
        FILE_FLAG_NO_BUFFERING 禁止对文件进行缓冲处理。文件只能写入磁盘卷的扇区块
        FILE_FLAG_RANDOM_ACCESS 针对随机访问对文件缓冲进行优化
        FILE_FLAG_SEQUENTIAL_SCAN 针对连续访问对文件缓冲进行优化
        FILE_FLAG_DELETE_ON_CLOSE 关闭了上一次打开的句柄后,将文件删除。特别适合临时文件
        也可在Windows NT下组合使用下述常数标记:
        SECURITY_ANONYMOUS,

        SECURITY_IDENTIFICATION,

        SECURITY_IMPERSONATION,

        SECURITY_DELEGATION,

        SECURITY_CONTEXT_TRACKING,

        SECURITY_EFFECTIVE_ONLY

    //第七个参数 HANDLE hTemplateFile

        hTemplateFile,hTemplateFile为一个文件或设备句柄,表示按这个参数给出的句柄为模板创建文件(就是将该句柄文件拷贝到lpFileName指定的路径,然后再打开)。

        它将指定该文件的属性扩展到新创建的文件上面,这个参数可用于将某个新文件的属性设置成与现有文件一样,并且这样会忽略dwAttrsAndFlags。

        通常这个参数设置为NULL,为空表示不使用模板,一般为空。

    

    返回值
        如执行成功,则返回文件句柄。
        INVALID_HANDLE_VALUE表示出错,会设置GetLastError。

        即使函数成功,但若文件存在,且指定了CREATE_ALWAYS 或 OPEN_ALWAYS,GetLastError也会设为ERROR_ALREADY_EXISTS

  FormatMessage 函数

    ● FormatMessage是一个Windows API函数。它的功能就是将GetLastError函数得到的错误信息(这个错误信息是数字代号)转化成字符串信息的函数。

      DWORD WINAPI FormatMessage (

        DWORD dwFlags, // source and processing options
        LPCVOID lpSource, // message source
        DWORD dwMessageId, // message identifier
        DWORD dwLanguageId, // language identifier
        LPTSTR lpBuffer, // message buffer
        DWORD nSize, // maximum size of message buffer
        va_list *Arguments // array of message inserts
        );

       ○ dwFlags

         标志位,决定如何说明lpSource参数,dwFlags的低位制定如何处理换行功能在输出缓冲区,也决定最大宽度的格式化输出行。[1]

       ○ lpSource
        根据dwFlags标志而定

       ○ dwMessageId
        请求的消息的标识符。当dwFlags标志为FORMAT_MESSAGE_FROM_STRING时会被忽略。[1]
       ○ dwLanguageId
        请求的消息的语言标识符。
       ○ LPTSTR lpBuffer
        接收错误信息描述的缓冲区指针。
       ○ nSize
        如果FORMAT_MESSAGE_ALLOCATE_BUFFER标志没有被指定,这个参数必须指定为输出缓冲区的大小,如果指定,这个参数指定为分配给输出缓冲区的最小数。[1]
       ○ Arguments
        保存格式化信息中的插入值的一个数组。

  LocalFree 函数
    ○ 功能:释放局部内存对象并使句柄失效
      ● hMem:局部内存对象的句柄,通过函数LocalAlloc或LocalReAlloc返回的。
    ○ 返回值
      ● 函数执行成功返回NULL,否则返回内存对象的句柄,要获得详细错误信息,调用GetLastError函数。

  在Windows系统中, 文件大小分为以下两种:

    物理大小
    GetFileSize 已弃用, 因为对于小文件还可以, 但是大文件会超过输出参数的范围
      DWORD WINAPI GetFileSize(
      _In_ HANDLE hFile, //文件句柄
      _Out_opt_ LPDWORD lpFileSizeHigh //文件大小 输出参数
      );
    

    GetFileSizeEx
    占用大小
    BOOL WINAPI GetFileSizeEx(
      _In_ HANDLE hFile, //文件句柄
      _Out_ PLARGE_INTEGER lpFileSize //文件大小 输出参数

  ReadFile

    BOOL ReadFile(
            HANDLE hFile,                  //文件的句柄
            LPVOID lpBuffer,                //用于保存读入数据的一个缓冲区
            DWORD nNumberOfBytesToRead,        //要读入的字节数
            LPDWORD lpNumberOfBytesRead,        //指向实际读取字节数的指针
            LPOVERLAPPED lpOverlapped         //结构体指针
            //如文件打开时指定了FILE_FLAG_OVERLAPPED,那么必须,用这个参数引用一个特殊的结构。
            //该结构定义了一次异步读取操作。否则,应将这个参数设为NULL
          );

    

    返回值: 成功返回非0
    同步下, 如果返回值不等于0.

    异步下, 参数5(lpOverlapped)不为NULL时, 当读到文件结尾时, 返回值为FALSE, GetLastError为ERROR_HANDLE_EOF.

  WriteFile
    BOOL WriteFile(
            HANDLE hFile,                  //文件句柄
            LPCVOID lpBuffer,                //数据缓存区指针
            DWORD nNumberOfBytesToWrite,       //你要写的字节数
            LPDWORD lpNumberOfBytesWritten,      //用于保存实际写入字节数的存储区域的指针
            LPOVERLAPPED lpOverlapped//OVERLAPPED  //结构体指针
          );

    返回值:

      成功返回非0的值

  1 #define UNICODE
  2 #include <tchar.h>
  3 #include <wchar.h>
  4 #include <windows.h>
  5 #include <exception>
  6
  7 class WindowsException:public std::exception
  8 {
  9 public:
 10     WindowsException(DWORD dwErrorCode):m_dwErrorCode(dwErrorCode)
 11     {
 12     FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
 13                     nullptr,
 14                     m_dwErrorCode,
 15                     0,
 16                     reinterpret_cast<LPWSTR>(&m_strErrorMsg),
 17                     0,
 18                     nullptr);
 19     }
 20     ~WindowsException()
 21     {
 22         LocalFree(m_strErrorMsg);
 23     }
 24     const TCHAR* what() const
 25     {
 26         return  m_strErrorMsg;
 27     }
 28 private:
 29     DWORD m_dwErrorCode;
 30     TCHAR * m_strErrorMsg;
 31 };
 32
 33 class MyFile
 34 {
 35 public:
 36         MyFile( const TCHAR *strFilePath ):m_hFile(INVALID_HANDLE_VALUE)                //构造函数
 37         {
 38             SetPath(strFilePath);
 39         }
 40
 41         ~MyFile()                                        //析构函数
 42         {
 43             if( m_hFile != INVALID_HANDLE_VALUE)
 44             {
 45                 CloseHandle(m_hFile);
 46             }
 47         }
 48         BOOL OpenFileW( _In_ DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE,        //读写权限
 49                             _In_ DWORD dwShareMode = FILE_SHARE_READ,                        //共享读文件操作
 50                             _In_ DWORD dwCreationDisposition = OPEN_ALWAYS,                    //如文件不存在则创建它
 51                             _In_ DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,            //默认属性
 52                             _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes = NULL,
 53                             _In_opt_ HANDLE hTemplateFile = NULL)
 54         {
 55             BOOL bRet = TRUE;
 56             m_hFile = CreateFileW( m_strFilePath,                                     //接收传递过来的参数
 57                                 dwDesiredAccess,
 58                                 dwShareMode,
 59                                 lpSecurityAttributes,
 60                                 dwCreationDisposition,
 61                                 dwFlagsAndAttributes,
 62                                 hTemplateFile);
 63             if( m_hFile == INVALID_HANDLE_VALUE)                    //不等于说明打开成功  相等的话说明成功
 64             {
 65                 bRet = FALSE;
 66                 throw WindowsException(GetLastError());
 67             }
 68             return bRet;
 69         }
 70         VOID SetPath( const TCHAR *strFilePath)
 71         {
 72             SIZE_T nstrLen = _tcslen(strFilePath) + sizeof(TCHAR);
 73             m_strFilePath = new TCHAR(nstrLen);
 74             _tcscpy_s(m_strFilePath, nstrLen, strFilePath);
 75         }
 76         const TCHAR *GetPath() const
 77         {
 78             return m_strFilePath;
 79         }
 80 private:
 81     HANDLE m_hFile;
 82     TCHAR *m_strFilePath;
 83
 84 };
 85
 86 int main()
 87 {
 88     try
 89     {
 90         MyFile clsFile;
 91         clsFile.SetPath( TEXT("demo.txt"));
 92         clsFile.OpenFile();
 93     }
 94     catch(WindowsException &exception)
 95     {
 96         MessageBoxW(nullptr, exception.what(), exception.what(), MB_OK);
 97     }
 98
 99 /*
100     HANDLE hFile = CreateFileW( L"Demo.txt",                            //文件名称
101                                  GENERIC_READ | GENERIC_WRITE,        //文件的访问权限
102                                  0,                                        //文件共享
103                                  nullptr,
104                                  OPEN_EXISTING,                        //文件必须已经存在。方式
105                                  FILE_ATTRIBUTE_NORMAL,                //默认属性
106                                  nullptr);                                //为空表示不使用模板,一般为空
107     if( hFile == INVALID_HANDLE_VALUE)    //如果存在的话弹出对话框
108                                             //INVALID_HANDLE_VALUE = -1 文件无法打开
109                                             //弹出对话框
110     {
111         MessageBox( nullptr, L"Error", L"Error", MB_OK );
112     }
113
114     CloseHandle(hFile);                        //关闭句柄
115
116 */
117     return 0;
118 }
时间: 2024-08-25 03:30:12

006 异步IO操作的相关文章

[.NET] 利用 async &amp; await 进行异步 IO 操作(整理中...)

利用 async & await 进行异步 IO 操作 可以使用异步函数访问文件.使用异步功能,可以调用异步方法,而不使用回调或拆分您在多个方法或 lambda 表达式中的代码. 若要使同步代码异步,则调用异步方法而不是一个同步方法并添加几个关键字到代码中. 您可能认为添加的以下原因 asynchrony 到文件访问调用: Asynchrony 建议于应用程序的响应能力更强.,因为是一个操作的 UI 线程可以执行其他工作. 如果 UI 线程必须执行需要很长时间的代码(例如,超过 50 毫秒),U

node.js零基础详细教程(4):node.js事件机制、node异步IO操作

第四章 建议学习时间3小时  课程共10章 学习方式:详细阅读,并手动实现相关代码 学习目标:此教程将教会大家 安装Node.搭建服务器.express.mysql.mongodb.编写后台业务逻辑.编写接口,最后完成一个完整的项目后台,预计共10天课程. node.js事件机制 node.js是单线程,但是通过事件和回调支持并发,可以实现非常高的性能. node.js所有的API都是通过异步调用.第一堂课的时候,我们写过一个同步和异步的示例(如下),当初说到:同步代码先执行完成,然后才执行异步

初始Python的异步IO操作(待完善)

1 import aiohttp 2 import asyncio 3 4 def consumer(): 5 r='' 6 while True: 7 n = yield r 8 if n: 9 r='200 OK' 10 print('客户取走了%s'%(str(n))) 11 else: 12 print('没货') 13 14 def producer(c): 15 n=0 16 c.send(None) 17 while n<5: 18 n+=1 19 print('生产了%s'%(s

Mina、Netty、Twisted一起学(九):异步IO和回调函数

用过JavaScript或者jQuery的同学都知道,JavaScript特别是jQuery中存在大量的回调函数,比如Ajax.jQuery的动画等. $.get(url, function() { doSomething1(); // (3) }); // (1) doSomething2(); // (2) 上面的代码是jQuery的Ajax,因为Ajax是异步的,所以在请求URL的过程中并不会堵塞程序,也就是程序运行到(1)并不用等待Ajax请求的结果,就继续往下运行(2).而$.get的

C中异步IO浅析之一:基于AIO_ABI的异步IO

相较于同步IO,异步IO请求发出后,应用程序不用阻塞,可以继续执行后面的业务流程,因此能够极大提高系统并发度和吞吐率.这也是为何许多SAN服务后端数据落盘常常采用异步IO读写的原因. C语言中提供了两套实现异步IO的方法,根据个人的理解,可以分为原生的AIO_ABI方法和集成的libaio方法.这篇主要介绍原生的异步IO的使用方法. 1. 头文件 和原生异步IO操作相关的函数对应的头文件包括: /usr/include/linux/aio_abi.h: 里面的内容如下: 此外,还有 /usr/i

同步IO,异步IO,阻塞IO,非阻塞IO的联系与区别

转载 POSIX 同步IO.异步IO.阻塞IO.非阻塞IO,这几个词常见于各种各样的与网络相关的文章之中,往往不同上下文中它们的意思是不一样的,以致于我在很长一段时间对此感到困惑,所以想写一篇文章整理一下. POSIX(可移植操作系统接口)把同步IO操作定义为导致进程阻塞直到IO完成的操作,反之则是异步IO 按POSIX的描述似乎把同步和阻塞划等号,异步和非阻塞划等号,但是为什么有的人说同步IO不等于阻塞IO呢?先来说说几种常见的IO模型吧. IO模型 这里统一使用Linux下的系统调用recv

Python异步IO之协程(一):从yield from到async的使用

引言:协程(coroutine)是Python中一直较为难理解的知识,但其在多任务协作中体现的效率又极为的突出.众所周知,Python中执行多任务还可以通过多进程或一个进程中的多线程来执行,但两者之中均存在一些缺点.因此,我们引出了协程. Tips 欲看完整代码请见:我的GitHub 为什么需要协程?首先,我们需要知道同步和异步是什么东东,不知道的看详解.简单来说:[同步]:就是发出一个“调用”时,在没有得到结果之前,该“调用”就不返回,“调用者”需要一直等待该“调用”结束,才能进行下一步工作.

关于异步IO与同步IO的写操作区别

最近这两天都在看IO相关的知识点.一开始太凌乱,太杂,不过终于整理清楚了.觉得杂乱是因为一开始以为异步IO等于非阻塞IO,这完全是两个概念, LINUX下的异步IO有两类,一类为glibc AIO,这类AIO是通过线程回调模拟,没细究;另一类是native AIO,是LINUX内核支持的,但只支持直接IO技术,关于直接IO技术.这里哆嗦两句,在一般情况下LINUX进行write系统调用时,通常是采用的延迟写入机制.在内核空间,有一个IO缓冲区,主要用来存储用户的写入数据,write系统调用成功返

[Python基础]006.IO操作

IO操作 输入输出 print raw_input input 文件 打开文件 关闭文件 读文件 写文件 文件指针 实例 输入输出 输入输出方法都是Python的内建函数,并且不需要导入任何的包就可以使用. print 简单控制台输出方法 print ... print 'content' raw_input 简单的控制台输入方法 raw_input(显示的内容....) num = raw_input('Please input a number:') // 输入一个数字 print num