多线程实现文件拷贝(Linux下C++)
多线程实现文件拷贝(Linux下C++)
我们应该都用过迅雷这种下载工具吧,迅雷下载工具中运用了多线程下载。多线程文件拷贝是实现多线程下载的基础,下面给出了多线程文件拷贝的实现代码:- //copyfile.cc
- #include <iostream>
- #include <cstring>
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <pthread.h>
- using namespace std;
- /************************************
- *使用指定线程实现从文件的拷贝
- *创建时间:2011.07.28
- *修改时间:2011.07.29
- *作者:hahaya
- ***********************************/
- //最大使用的线程数
- const int MAX_THREADS = 5;
- typedef struct TAG_INFO
- {
- char *fromfile; //源地址
- char *tofile; //目的地址
- int num; //启动的第i-1个进程
- }info;
- //st_size的类型为__off_t
- int get_size(const char *filename)
- {
- struct stat st;
- memset(&st, 0, sizeof(st));
- stat(filename, &st);
- return st.st_size;
- }
- void* threadDL(void *param)
- {
- info info1 = *((info*)param);
- FILE *fin = fopen(info1.fromfile, "r+");
- FILE *fout = fopen(info1.tofile, "w+");
- int size = get_size(info1.fromfile);
- //将文件指针分别设置在每个线程要读和写的位置
- fseek(fin, size*(info1.num)/MAX_THREADS, SEEK_SET);
- fseek(fout, size*(info1.num)/MAX_THREADS, SEEK_SET);
- char buff[1024] = {'\0'};
- int len = 0;
- int total = 0;
- while((len = fread(buff, 1, sizeof(buff), fin)) > 0)
- {
- fwrite(buff, 1, len, fout);
- total += len;
- //如果读入的数据大于文件总大小除线程总数则停止读入,因为每个线程要读或写的数据就等于文件总大小除线程总数
- //可能会多写入一些数据,下一次写入时会覆盖多写入的数据,所以不用担心
- if(total > size/MAX_THREADS)
- {
- break;
- }
- }
- fclose(fin);
- fclose(fout);
- }
- int main(int argc, char *argv[])
- {
- //先创建一个与文件1同样大小的文件
- creat(argv[2], 0777);
- truncate(argv[2], get_size(argv[1]));
- pthread_t pid[MAX_THREADS];
- info info1;
- //启动指定线程数的线程
- for(int i = 0; i < MAX_THREADS; i++)
- {
- memset(&info1, 0, sizeof(info1));
- info1.fromfile = argv[1];
- info1.tofile = argv[2];
- info1.num = i;
- pthread_create(&pid[i], NULL, threadDL, (void*)&info1);
- }
- //等待线程结束
- for(int j = 0; j < MAX_THREADS; j++)
- {
- //pthread_join不能用在创建进程的for循环中,否则创建第一个进程后会等待第一个进程结束后创建第二个进程
- pthread_join(pid[j], NULL);
- }
- cout << "file copy success......" << endl;
- return 0;
- }
程序运行截图:
复制后的文件是完整的,可以解压,如下图:
评论暂时关闭