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 #include <iostream>
  2 #include <tchar.h>
  3 #include <windows.h>
  4 #include <exception>
  5 
  6 //class WindowsException:public std::exception
  7 class WindowsException
  8 {
  9 public:
 10     WindowsException(DWORD dwErrorCode):m_dwErrorCode(dwErrorCode)
 11     {
 12         FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
 13             nullptr, m_dwErrorCode, 0, reinterpret_cast<LPWSTR>(&m_strErrorMsg), 0, nullptr);
 14     }
 15     ~WindowsException()
 16     {
 17         LocalFree(m_strErrorMsg);
 18     }
 19     const TCHAR* what() const
 20     {
 21         return m_strErrorMsg;
 22     }
 23     
 24 private:
 25     DWORD m_dwErrorCode;
 26     TCHAR* m_strErrorMsg;
 27 };
 28 
 29 
 30 class MyFile
 31 {
 32 public:
 33     //默认构造函数
 34     MyFile(const TCHAR *strFilePath = TEXT("")):m_hFile(INVALID_HANDLE_VALUE)
 35     {
 36         SetPath(strFilePath);
 37     }
 38 
 39     //默认析构函数
 40     ~MyFile()
 41     {
 42         if (m_hFile != INVALID_HANDLE_VALUE)
 43         {
 44             CloseHandle(m_hFile);
 45         }
 46     }
 47 
 48     //打开文件操作
 49     BOOL OpenFile(DWORD dwDesiredAccess = GENERIC_READ | GENERIC_WRITE,
 50         _In_  DWORD dwShareMode = FILE_SHARE_READ,
 51         _In_      DWORD dwCreationDisposition = OPEN_ALWAYS,
 52         _In_      DWORD dwFlagsAndAttributes = FILE_ATTRIBUTE_NORMAL,
 53         _In_opt_  LPSECURITY_ATTRIBUTES lpSecurityAttributes = nullptr,
 54         _In_opt_  HANDLE hTemplateFile = nullptr
 55         )
 56     {
 57         BOOL bRet = TRUE;
 58         m_hFile = CreateFile(m_strFilePath, dwDesiredAccess, dwShareMode, lpSecurityAttributes, dwCreationDisposition, dwFlagsAndAttributes, hTemplateFile);
 59         if (m_hFile == INVALID_HANDLE_VALUE)        //如果
 60         {
 61             bRet = FALSE;
 62             throw WindowsException(GetLastError());
 63         }
 64         return bRet;
 65     }
 66 
 67     //设置文件路径
 68     VOID SetPath(const TCHAR *strFilePath)
 69     {
 70         SIZE_T nstrLen = _tcslen(strFilePath) + sizeof(TCHAR);
 71         m_strFilePath = new TCHAR[nstrLen];
 72         _tcscpy_s(m_strFilePath, nstrLen, strFilePath);
 73     }
 74 
 75     //获取文件路径
 76     const TCHAR *GetPath() const
 77     {
 78         return m_strFilePath;
 79     }
 80 
 81     const HANDLE GetHandle() const
 82     {
 83         return m_hFile;
 84     }
 85 
 86 private:
 87     HANDLE m_hFile;
 88     TCHAR *m_strFilePath;
 89 
 90 };
 91 
 92 
 93 int main()
 94 {
 95     try
 96     {
 97         MyFile clsFile;
 98         clsFile.SetPath(TEXT("demo.txt"));
 99         clsFile.OpenFile();
100 
101         //取大小
102         // 物理大小
103         LARGE_INTEGER largeFileSize = { 0 };
104         GetFileSizeEx(clsFile.GetHandle(), &largeFileSize);
105         std::cout << "File Size:" << largeFileSize.QuadPart << std::endl;
106 
107         // 磁盘上占用的大小
108         largeFileSize.LowPart = GetCompressedFileSize(clsFile.GetPath(), (LPDWORD)(&(largeFileSize.HighPart)));
109         std::cout << "File Compressed Size:" << largeFileSize.QuadPart << std::endl;
110 
111         //同步I/O    FILE_FLAG_OVERLAPPED
112                     //这个标志位 是否是进行异步IO操作
113                     //如果做同步I/0确保不要有这个标志位
114         //
115         BYTE bBuffer[MAXBYTE] = { 0 };
116         DWORD dwReadSize = 0;
117 
118         //64位的值操作的偏移量
119         LARGE_INTEGER largeBegin = { 0 };
120         largeFileSize.LowPart = 100;
121 
122         //移动文件位置
123         SetFilePointerEx(clsFile.GetHandle(), largeFileSize, nullptr, FILE_BEGIN);
124 
125         if (ReadFile(clsFile.GetHandle(), bBuffer, MAXBYTE, &dwReadSize, nullptr))
126             std::cout << (char*)bBuffer << std::endl << std::endl <<"读取长度:" <<dwReadSize << std::endl;
127         //
128         DWORD dwWitre = 0;
129         if (WriteFile(clsFile.GetHandle(), bBuffer, MAXBYTE, &dwWitre, nullptr))
130             std::cout << "写入成功!" << std::endl;
131 
132         //文件本身大小是22 设置位1024
133         //设置文件尾
134         largeFileSize.QuadPart = 1024;
135         SetFilePointerEx(clsFile.GetHandle(), largeFileSize, nullptr, FILE_BEGIN);
136         SetEndOfFile(clsFile.GetHandle());
137     }
138     catch (WindowsException &exception)
139     {
140         MessageBoxW(nullptr, exception.what(), exception.what(), MB_OK);
141     }
142 
143     /*
144     HANDLE hFile = CreateFileW(L"Demo.txt", GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,nullptr);
145     if (hFile == INVALID_HANDLE_VALUE)
146     {
147         MessageBox(nullptr, L"Error", L"Error", MB_OK);
148     }
149     CloseHandle(hFile);
150     */
151     system("pause");
152     return 0;
153 }
原文地址:https://www.cnblogs.com/sdk123/p/6850748.html