zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    Indy10 系列(一)——获取最新的Indy源码
    Oracle9i中关于select into的执行过程 (转)
    Oracle创建删除用户、角色、表空间、导入导出数据库命令行方式总结(转)
    手动创建Oracle 11g数据库(转载)
    Indy10 系列(四)——编译Indy源码
    Indy10 系列(二)——获取最新的Indy源码
    Delphi 2010手动安装indy10.5.7
    Indy10 系列(三)——获取最新的Indy源码
    Indy10 系列(五)——安装Indy控件,重新编译Lazarus
    Unix文化RTFM
  • 原文地址:https://www.cnblogs.com/sdk123/p/6850748.html
Copyright © 2011-2022 走看看