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 }
原文地址:https://www.cnblogs.com/sdk123/p/6938399.html