用线程的方式实现一个目录的拷贝(只考虑目录和普通文件)

本文介绍了一种使用多线程技术实现目录及其文件拷贝的方法。通过解析路径并利用线程来加速文件拷贝过程,提高了拷贝效率。文章详细展示了如何创建线程、处理文件读写操作及目录结构的递归复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用线程的方式实现一个目录的拷贝(只考虑目录和普通文件)

#include <sys/types.h>
#include <dirent.h>
#include <stdio.h>
#include <pthread.h>
#include <string.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

#define MAX 1024

struct ctwo{
    char *old; 
    char *new;
};

void* thread(void* arg)
{
	//先将两个路径名解析出来 
	struct ctwo * p = (struct ctwo *)arg;

    int fp1 = open(p -> old,O_RDONLY);
    if(fp1 == -1)
    {
        perror("open p1 error\n");
        goto cp_return;
    }
    int fp2 = open(p-> new,O_WRONLY | O_CREAT | O_TRUNC,0777);
    if(fp2 == -1)
    {
        perror("open p2 error\n");
        goto cp_return;
    }

    int ret;
    char buf[MAX]={0};  
    while(1)
    {
        ret = read(fp1,buf,MAX);
        if(ret == 0)//文件为空或者已经读完
        {
            break;
        }
        else if(ret >0)
        {
            int ret_write = write(fp2,buf,ret);
            if(ret_write == -1)
            {
                perror("write error\n");
            }
        }
        else{
            perror("read error\n");
        }

    } 

cp_return:
	free(arg);
	close(fp1);
	close(fp2);

	return NULL;
}

int cp(char *p,char *pre)
{
    int len = strlen(p)-1;
    while(*(p+len) != '/')
    {
        len--;
    }
    char *p1=p+len+1;

    char filename[MAX]={0};//新的目录名
    sprintf(filename,"%s/%s",pre,p1);

    //创建一个新目录
    mkdir(filename,0777);

    //更新目的地
    pre = filename;

    //打开目录
    DIR *dir = opendir(p);
    if(dir == NULL)
    {
        perror("opendir error\n");
    }

    //读文件流里面的文件名
    struct dirent *fp = NULL;
    while(fp = readdir(dir))
    {     
        if(strcmp(fp->d_name,".")==0 || strcmp(fp->d_name,"..")==0)//***此处一定要判断是否等于0***
        {
            continue;
        }
        //将读到的文件名拼接成完整的文件名
        char file_old[MAX]={0};
        sprintf(file_old,"%s/%s",p,fp->d_name);
        
        //拼接新的文件文件名
        char file_new[MAX]={0};
        sprintf(file_new,"%s/%s",pre,fp->d_name);

        //判断文件类型
        struct stat st;
        lstat(file_old,&st);

        if(S_ISREG(st.st_mode)||S_ISLNK(st.st_mode))
        {
            struct ctwo *t =malloc(sizeof(*t));

            t -> old = file_old;
            t -> new = file_new;

            pthread_t th;
            pthread_create(&th,NULL,thread,(void*)t);

            pthread_join(th,NULL);
        }
        else if(S_ISDIR(st.st_mode))
        {

            cp(file_old,pre);
        }
   
    }

    closedir(dir);
    return -1;

}
int main(int argc,char*argv[])
{
    if(argc > 3)
    {
        printf("input error\n");
        return -1;
    }
    char *p;
    char *pre;
    p = argv[1];
    pre = argv[2];
    cp(p,pre);

    return 0;

}

***注意:1、进程文件传参的转换
			2、目录文件创建的用 mkdir***
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值