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 }