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 }