• 012 CopyFile


      1 #include <windows.h>
      2 #include <iostream>
      3 #define IOCP_KEY_READ 1
      4 #define IOCP_KEY_WRITE 2
      5 
      6 int main()
      7 {
      8     LPCTSTR lpstrSrcFilePath = TEXT("Demo.exe");
      9     LPCTSTR lpstrDesFilePath = TEXT("Demo-Clone.exe");
     10 
     11     BOOL bOK = FALSE;
     12     do {
     13         //打开设备
     14         HANDLE hSrcFile = CreateFile(lpstrSrcFilePath, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, nullptr);
     15         if (hSrcFile == INVALID_HANDLE_VALUE)
     16             break;
     17 
     18         HANDLE hDestFile = CreateFile(lpstrDesFilePath, FILE_GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, hSrcFile);
     19         if (hDestFile == INVALID_HANDLE_VALUE)
     20             break;
     21 
     22         //获取原文件的大小
     23         LARGE_INTEGER liFileSize;
     24         if (!GetFileSizeEx(hSrcFile, &liFileSize))
     25             break;
     26 
     27         //设置现在的位置
     28         if (!SetFilePointerEx(hDestFile, liFileSize, nullptr, FILE_BEGIN))
     29             break;
     30 
     31         //设置文件末尾
     32         if (!SetEndOfFile(hDestFile))
     33             break;
     34 
     35         //获取磁盘大小
     36         DWORD dwBytePerSectro;
     37         if (!GetDiskFreeSpace(TEXT("D:"), nullptr, &dwBytePerSectro, nullptr, nullptr))
     38             break;
     39 
     40         //获取硬盘信息
     41         SYSTEM_INFO sysInfo = { 0 };
     42         GetSystemInfo(&sysInfo);
     43 
     44         //创建IOCP
     45         HANDLE hIOCP = CreateIoCompletionPort(INVALID_HANDLE_VALUE, nullptr, 0, sysInfo.dwNumberOfProcessors);
     46         if (hIOCP == NULL)
     47         {
     48             DWORD dwError = GetLastError();
     49             if (dwError != ERROR_ALIAS_EXISTS)
     50             {
     51                 break;    //执行失败
     52             }
     53         }
     54         hIOCP = CreateIoCompletionPort(hSrcFile, hIOCP, IOCP_KEY_READ, sysInfo.dwNumberOfProcessors);
     55         hIOCP = CreateIoCompletionPort(hDestFile, hIOCP, IOCP_KEY_WRITE, sysInfo.dwNumberOfProcessors);
     56 
     57         OVERLAPPED oRead = { 0 }, oWrite = { 0 };
     58 
     59         PostQueuedCompletionStatus(hIOCP, 0, IOCP_KEY_WRITE, &oWrite);
     60 
     61         DWORD dwByteTrans = 0;
     62         ULONG_PTR ulKey = 0;
     63         LPOVERLAPPED lpOverlapped = nullptr;
     64 
     65         //扇区大小的倍数
     66         //扇区大小读 512K
     67         SIZE_T sizeLen = dwBytePerSectro * 1024;
     68         //分配一段内存空间
     69         LPVOID lpAddr = VirtualAlloc(nullptr, sizeLen, MEM_RESERVE | MEM_COMMIT , PAGE_READWRITE);
     70 
     71         while (true)
     72         {
     73             BOOL bRet = GetQueuedCompletionStatus(hIOCP, &dwByteTrans, &ulKey, &lpOverlapped, INFINITE);
     74             if (bRet == FALSE)
     75             {
     76                 if (lpOverlapped == NULL)
     77                 {
     78                     break;
     79                 }
     80                 else
     81                 {
     82                     continue;
     83                 }
     84 
     85             }
     86 
     87             switch (ulKey)
     88             {
     89             case IOCP_KEY_READ:
     90                 {
     91                     //WriteFIle()    //写操作
     92                     WriteFile(hDestFile, lpAddr, sizeLen, nullptr, &oWrite);
     93                     
     94                     LARGE_INTEGER liReadLen;
     95                     liReadLen.QuadPart = dwByteTrans;
     96 
     97                     oRead.Offset += liReadLen.LowPart;
     98                     oRead.OffsetHigh += liReadLen.HighPart;
     99                     //offset
    100                 }
    101                 break;
    102             case IOCP_KEY_WRITE:
    103                 {
    104                     //更新offset
    105                     
    106                     LARGE_INTEGER liWriteLen;
    107                     liWriteLen.QuadPart = dwByteTrans;
    108 
    109                     oWrite.Offset += liWriteLen.LowPart;
    110                     oWrite.OffsetHigh += liWriteLen.HighPart;
    111                     //ReadFile 判断文件的长度
    112                     ReadFile(hSrcFile, lpAddr, sizeLen, nullptr, &oRead);
    113 
    114                 }
    115             }
    116         }
    117 
    118         CloseHandle(hSrcFile);
    119         CloseHandle(hDestFile);
    120         bOK = TRUE;
    121     } while (false);
    122     if (!bOK)
    123     {
    124         DWORD dwError = GetLastError();
    125         std::cout << "Error:" << dwError << std::endl;
    126         //Error
    127     }
    128     
    129 
    130 
    131 
    132     return 0;
    133 }
  • 相关阅读:
    0593. Valid Square (M)
    0832. Flipping an Image (E)
    1026. Maximum Difference Between Node and Ancestor (M)
    0563. Binary Tree Tilt (E)
    0445. Add Two Numbers II (M)
    1283. Find the Smallest Divisor Given a Threshold (M)
    C Primer Plus note9
    C Primer Plus note8
    C Primer Plus note7
    C Primer Plus note6
  • 原文地址:https://www.cnblogs.com/sdk123/p/6938399.html
Copyright © 2020-2023  润新知