C++多线程复制文件
使用文件读写复制问文件的线程函数: DWORD WINAPI CopyThread(LPVOID lpParam) { CCopyFileDlg *dlg=(CCopyFileDlg*)lpParam; CFile file1(dlg->m_Src,CFile::modeRead); CFile file2(dlg->m_Dest,CFile::modeCreate | CFile::modeWrite | CFile::modeNoTruncate); //注意CFile::modeNoTruncate char buff[1024*400]={0}; UINT read=file1.Read(buff,sizeof(buff)); DWORD Len=file1.GetLength(); DWORD Have=0; while(read>0) { file2.Write(buff,read); file2.SeekToEnd(); //移动文件指针,否则会覆盖 Have+=read; PostMessage(dlg->m_hWnd,WM_READ,Len,Have); read=file1.Read(buff,sizeof(buff)); } return 0; } 使用内存映射复制线程函数: DWORD WINAPI ThreadProc(LPVOID lpParameter) { CCopyFileDlg *dlg=(CCopyFileDlg*)lpParam; HANDLE hFile=CreateFile(dlg->src,GENERIC_READ | GENERIC_WRITE,PAGE_READONLY,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); DWORD dwFileSizeHigh; __int64 qwFileSize = GetFileSize(hFile, &dwFileSizeHigh); qwFileSize |= (((__int64)dwFileSizeHigh) << 32); HANDLE hFile2=CreateFile(dlg->dest,GENERIC_READ | GENERIC_WRITE,PAGE_READWRITE,NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,NULL); if (hFile == INVALID_HANDLE_VALUE || hFile2 == INVALID_HANDLE_VALUE) { TRACE("创建文件对象失败,错误代码:%d\r\n", GetLastError()); return 0; } HANDLE hFileMapping=CreateFileMapping(hFile, NULL,PAGE_READWRITE,0,qwFileSize,NULL); HANDLE hFileMapping2=CreateFileMapping(hFile2, NULL,PAGE_READWRITE,0,qwFileSize,NULL); if (hFileMapping || hFileMapping2 == NULL) { TRACE("创建文件映射对象失败,错误代码:%drn", GetLastError()); return 0; } SYSTEM_INFO sys; GetSystemInfo(&sys); DWORD dwGran =sys.dwAllocationGranularity; //系统粒度的大小 // 关闭文件对象 CloseHandle(hFile); CloseHandle(hFile2); // 偏移地址 __int64 qwFileOffset = 0; // 块大小 DWORD dwBlockBytes = 100 * dwGran; if (qwFileSize < 100 * dwGran) dwBlockBytes = (DWORD)qwFileSize; //int pos=dwBlockBytes*100/(qwFileSize*1.0); while (qwFileSize > 0) { // 映射视图 LPBYTE lpbMapAddress = (LPBYTE)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS, (DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),dwBlockBytes); LPBYTE lpbMapAddress2 = (LPBYTE)MapViewOfFile(hFileMapping2,FILE_MAP_ALL_ACCESS, (DWORD)(qwFileOffset >> 32), (DWORD)(qwFileOffset & 0xFFFFFFFF),dwBlockBytes); if (lpbMapAddress && lpbMapAddress2 == NULL) { TRACE("映射文件映射失败,错误代码:%drn", GetLastError()); return 0; } memcpy(lpbMapAddress2,lpbMapAddress,dwBlockBytes); // 撤消文件映像 UnmapViewOfFile(lpbMapAddress); UnmapViewOfFile(lpbMapAddress2); // 修正参数 qwFileOffset += dwBlockBytes; qwFileSize -= dwBlockBytes; if(qwFileSize < dwBlockBytes) dwBlockBytes=qwFileSize; } CloseHandle(hFileMapping); CloseHandle(hFileMapping2); return 0; } 另一个使用内存映射复制文件,限小于4G的文件 DWORD WINAPI MapThread(LPVOID lpParam) { CCopyFileDlg *dlg=(CCopyFileDlg*)lpParam; HANDLE hFile=CreateFile(dlg->m_Src,GENERIC_READ,NULL,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,NULL); HANDLE hFile2=CreateFile(dlg->m_Dest,GENERIC_WRITE | GENERIC_READ,NULL,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); if(INVALID_HANDLE_VALUE==hFile || INVALID_HANDLE_VALUE==hFile2 ) { AfxMessageBox(_T("打开文件失败")); return 0; } DWORD len=GetFileSize(hFile,0); HANDLE hMapping=CreateFileMapping(hFile,NULL,PAGE_READONLY,0,0,NULL); HANDLE hMapping2=CreateFileMapping(hFile2,NULL,PAGE_READWRITE,0,len,NULL); if(hMapping==NULL || hMapping2==NULL ) { AfxMessageBox(_T("CreateFileMapping失败")); return 0; } SYSTEM_INFO systemInfo; GetSystemInfo(&systemInfo); DWORD dwFileOffsetLow=0; DWORD dwGran=systemInfo.dwAllocationGranularity*10; LPVOID pAdd=NULL,pAdd2=NULL; DWORD read=0; if(dwGran > len) { dwGran=len; } while(dwFileOffsetLow < len) { if(len-dwFileOffsetLow<dwGran) read=len-dwFileOffsetLow; else read=dwGran; pAdd=MapViewOfFile(hMapping,FILE_MAP_READ,0,dwFileOffsetLow,read); pAdd2=MapViewOfFile(hMapping2,FILE_MAP_WRITE,0,dwFileOffsetLow,read); if(NULL==pAdd || NULL==pAdd2) { AfxMessageBox(_T("MapViewOfFile失败")); return 0 ; } else { CopyMemory(pAdd2,pAdd,read); dwFileOffsetLow+=read; } UnmapViewOfFile(pAdd); UnmapViewOfFile(pAdd2); PostMessage(dlg->m_hWnd,WM_READ,len,dwFileOffsetLow); } CloseHandle(hMapping); CloseHandle(hMapping2); return 0; }