程序的执行方式为:
./a.out n src dst (其中n代表线程数量)
/************************************************************************* * File Name: copyfile.c * Author: lixiaogang * Function: 线程拷贝文件 * Mail: 2412799512@qq.com * Created Time: 2017年06月12日 星期一 21时32分08秒 ************************************************************************/
#include<stdio.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<fcntl.h>
#include<pthread.h>
#include<string.h>
#include<unistd.h>
typedef struct
{
char src_file[1024];
char dst_file[1024];
int start;
int length;
}Args;
/* 封装出错打印函数 */
void sys_err(const char *ptr,int num)
{
perror(ptr);
exit(num);
}
void *pthreadFunc(void *args)
{
Args *arg = (Args *)args;
int src_fd = open(arg->src_file,O_RDONLY);
int dst_fd = open(arg->dst_file,O_WRONLY);
lseek(src_fd,arg->start,SEEK_SET);
lseek(dst_fd,arg->start,SEEK_SET);
char buf[1024];
while(arg->length > 0)
{
memset(buf,0x00,sizeof(buf));
int len = read(src_fd,buf,arg->length);
if(len < 0)
{
break;
}
/* 向文件写入真实读到的字节数 */
write(dst_fd,buf,len);
arg->length -= len;
}
free(arg);
close(src_fd);
close(dst_fd);
}
/* 文件拷贝实现 */
void copyFile(int num,const char *src,const char *dst)
{
struct stat st;
int i;
int flag = stat(src,&st);
if(flag < 0)
{
sys_err("stat",-1);
}
/* num个线程,平均每个线程负责拷贝的数据块大小*/
int averageSize = st.st_size / num;
/* num线程个数不确定,所以把余下的数据块给最后线程*/
int lastSize = st.st_size % num;
int dstfd = open(dst,O_CREAT,0777);
if(dstfd < 0)
{
sys_err("open",-2);
}
/*为目标文件分配源文件大小的内存空间*/
ftruncate(dstfd,st.st_size);
close(dstfd);
pthread_t *tid = (pthread_t *)malloc(sizeof(pthread_t) * num);
if(NULL == tid)
{
sys_err("pthread_t malloc",-3);
}
for(i = 0;i < num; ++i)
{
Args *arg = (Args *)malloc(sizeof(Args));
strcpy(arg->src_file,src);
strcpy(arg->dst_file,dst);
arg->start = averageSize * i;
/* 判断是否为最后的一个线程,若是,则其拷贝数据块+lastsSize */
if(i == num - 1)
arg->length = averageSize + lastSize;
else
arg->length = averageSize;
/* 创建线程 */
pthread_create(tid + i,NULL,pthreadFunc,(void *)arg);
/* 回收线程所占用的内存资源 */
}
for(i = 0; i< num; ++i)
{
pthread_join(tid[i],NULL);
}
free(tid);
}
int main(int argc,char *argv[])
{
/* ./a.out n src dst */
if(argc != 4)
{
printf("Usage: filename num src dst.\n");
return -1;
}
const char *src = argv[2];
const char *dst = argv[3];
int num = atoi(argv[1]);
/*拷贝文件*/
copyFile(num,src,dst);
return 0;
}