多线程复制文件

来源:互联网 发布:电脑护眼知乎 编辑:程序博客网 时间:2024/06/04 20:01
#include <stdio.h>#include <windows.h>#include <stdlib.h>#include <iostream>#define _CRT_SECURE_NO_WARNINGSusing namespace std;CRITICAL_SECTION g_csThreadCode;volatile long g_nNum; //全局资源struct ThreadInfo{int i;int flen;//fLenint blocklen;//blockLenFILE* a;//fsrcFILE* b;//ftmpint threadnum;//N}Info;DWORD WINAPI Fun(void* pPM){//由于创建线程是要一定的开销的,所以新线程并不能第一时间执行到这来//int nThreadNum = *(int *)pPM; //子线程获取参数EnterCriticalSection(&g_csThreadCode);//InterlockedIncrement(&g_nNum);      // 全局变量//Sleep(0);printf("第 %d个线程正在执行!\n", g_nNum+1);//写入文件int offset = g_nNum*Info.blocklen;//i*blockLen; //计算偏移量 fseek(Info.a, offset, SEEK_SET);fseek(Info.b, offset, SEEK_SET);int count = 0;  //统计写入ftmp的数量if (g_nNum == Info.threadnum - 1)Info.blocklen = Info.flen - Info.blocklen*(Info.threadnum - 1);  //最后一块的长度while (count<Info.blocklen && !feof(Info.a)){fputc(fgetc(Info.a), Info.b);count++;}//写入结束g_nNum++;LeaveCriticalSection(&g_csThreadCode);return 0;}int main(){g_nNum = 0;int THREAD_NUM; //子线程个数printf("请输入线程数:\n");cin >> THREAD_NUM;//打开要复制的文件FILE *fsrc = fopen("D:\\document\\123.mp4", "rb");  // 源文件fseek(fsrc, 0, SEEK_END);int fLen = ftell(fsrc);  // 文件长度printf("文件长度:%d\n", fLen);int blockLen = fLen / THREAD_NUM;   // 每一块的长度printf("blockLen:%d\n", blockLen);//创建大小相同的文件FILE *ftmp;  // 临时文件,char tName[20];char tdir[60] = "D:\\document\\";sprintf(tName, "new123.mp4");//生成文件名strcat(tdir, tName);  //产生临时目录ftmp = fopen(tdir, "wb");  // 生成临时文件fseek(ftmp, fLen - 1, 0);//指定大小fputc(0, ftmp);HANDLE  handle[MAX_PATH];InitializeCriticalSection(&g_csThreadCode);int i = 0;Info.a = fsrc;Info.b = ftmp;Info.blocklen = blockLen;Info.flen = fLen;Info.threadnum = THREAD_NUM;while (i < THREAD_NUM){//等子线程接收到参数时主线程可能改变了这个i的值handle[i] = CreateThread(NULL, 0, Fun, &Info, 0, NULL); i++;}//保证子线程已全部运行结束WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);DeleteCriticalSection(&g_csThreadCode);system("pause");return 0;}

// MultipleTask.cpp: 定义控制台应用程序的入口点。//每个下载是单独的一个线程#include "stdafx.h"#include "DownloadInfo.h"#include <sstream>//解除最多等待64个线程限制DWORD SyncWaitForMultipleObjs(HANDLE * handles, int count){int waitingThreadsCount = count;int index = 0;DWORD res = 0;while (waitingThreadsCount >= MAXIMUM_WAIT_OBJECTS){res = WaitForMultipleObjects(MAXIMUM_WAIT_OBJECTS, &handles[index], TRUE, INFINITE);if (res == WAIT_TIMEOUT || res == WAIT_FAILED){puts("1. Wait Failed.");return res;}waitingThreadsCount -= MAXIMUM_WAIT_OBJECTS;index += MAXIMUM_WAIT_OBJECTS;}if (waitingThreadsCount > 0){res = WaitForMultipleObjects(waitingThreadsCount, &handles[index], TRUE, INFINITE);if (res == WAIT_TIMEOUT || res == WAIT_FAILED){puts("2. Wait Failed.");}}return res;}LPWSTR MtoW(char* temp, LPTSTR buffera) {DWORD dwNum = MultiByteToWideChar(CP_ACP, 0, temp, -1, NULL, 0);//计算这个GB2312实际有几个字组成wchar_t* pwText;pwText = new wchar_t[dwNum];if (!pwText){delete[]pwText;}MultiByteToWideChar(CP_ACP, 0, temp, -1, pwText, dwNum);//把GB2312变成UNICODEwcscpy_s(buffera, MAX_PATH, pwText);delete[]pwText;return buffera;}bool InternetDownload(const string &URL, const string &FN){CString strURL, strFN;strURL = URL.c_str();strFN = FN.c_str();CInternetSession internetSession(L"DownloaderWsl",1,PRE_CONFIG_INTERNET_ACCESS,NULL,NULL,0);BOOL bSucceed = TRUE;try{// 统一以二进制方式下载DWORD       dwFlag = INTERNET_FLAG_TRANSFER_BINARY | INTERNET_FLAG_DONT_CACHE | INTERNET_FLAG_RELOAD;//子类对基类进行了强制类型转换,利用函数打开要下载的网址链接 wangsl//将要下载文件的信息CHttpFile   * pF = (CHttpFile*)internetSession.OpenURL(strURL, 1, dwFlag);// 得到文件大小CString      str;pF->QueryInfo(HTTP_QUERY_CONTENT_LENGTH, str);int   nFileSize = _ttoi(str);//文件大小,将字符串转换成整形//int nTotalSize = nFileSize;if (pF != NULL){//创建下载文件,不存在就创建,存在就直接写入 wangslCFile cf;if (!cf.Open(strFN, CFile::modeCreate | CFile::modeWrite, NULL)){return FALSE;}//BYTE Buffer[8192];//为Buffer分配空间 wangslZeroMemory(Buffer, sizeof(Buffer));int nReadLen = 0;while ((nReadLen = pF->Read(Buffer, sizeof(Buffer))) > 0)//每次读取固定长度到Buffer中,返回实际读取的长度 wangsl{cf.Write(Buffer, nReadLen);//在创建的文件中写入读取的内容 wangslnFileSize -= nReadLen;TRACE("剩余:%d\n", nFileSize);}cf.Close();pF->Close();delete pF;}}catch (CInternetException& e){char szBuffer[128];ZeroMemory(szBuffer, sizeof(szBuffer));LPTSTR buffer = NULL;MtoW(szBuffer, buffer);e.GetErrorMessage(buffer, sizeof(buffer), NULL);TRACE("InternetDownload, Exception: %s ", buffer);}catch (...){TRACE("InternetDownload, Exception: ... ");}internetSession.Close();if (!bSucceed)DeleteFile(strFN);return bSucceed;}unsigned int __stdcall Fun(void *pPM){Info nThreadNum = *(Info *)pPM;InternetDownload(nThreadNum.url, nThreadNum.filename);return 0;}int main(){//接收网址数据int n = 0;cout << "请输入要下载的任务数:" << endl;cin >> n;cout << "请输入任务的URL:" << endl;for (int k = 0; k < n ; k++){cin >> FN1[k].url;}//接收完毕 创建线程HANDLE  handle[MAX_PATH];int i = 0;while (i < n){int nNum = GetTickCount();char szFilePath[MAX_PATH] = { 0 };sprintf(szFilePath, "%d%s", nNum, FILE_TYPE);FN1[i].filename = szFilePath;handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &FN1[i], 0, NULL);Sleep(5);i++;}SyncWaitForMultipleObjs(handle, n);for (i = 0; i < n; i++)CloseHandle(handle[i]);system("pause");    return 0;}


原创粉丝点击