您的位置:首页 > 运维架构 > Linux

多线程实现文件拷贝(Linux下C++)

2011-07-29 22:48 726 查看
    我们应该都用过迅雷这种下载工具吧,迅雷下载工具中运用了多线程下载。多线程文件拷贝是实现多线程下载的基础,下面给出了多线程文件拷贝的实现代码:

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

}


程序运行截图:



复制后的文件是完整的,可以解压,如下图:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息