• 欢迎访问开心洋葱网站,在线教程,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站,欢迎加入开心洋葱 QQ群
  • 为方便开心洋葱网用户,开心洋葱官网已经开启复制功能!
  • 欢迎访问开心洋葱网站,手机也能访问哦~欢迎加入开心洋葱多维思维学习平台 QQ群
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏开心洋葱吧~~~~~~~~~~~~~!
  • 由于近期流量激增,小站的ECS没能经的起亲们的访问,本站依然没有盈利,如果各位看如果觉着文字不错,还请看官给小站打个赏~~~~~~~~~~~~~!

C++多线程复制文件

OC/C/C++ 水墨上仙 1691次浏览

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;
}


开心洋葱 , 版权所有丨如未注明 , 均为原创丨未经授权请勿修改 , 转载请注明C++多线程复制文件
喜欢 (0)
加载中……