现在的位置: 首页 > 综合 > 正文

linux 下面实现目录的拷贝:COPY.c

2013年12月03日 ⁄ 综合 ⁄ 共 7654字 ⁄ 字号 评论关闭

/*这是一个目录复制程序:COPY.c,起可执行文件为COPY。运行时,自带两个参数:argv[1]和argv[2]。
*其中argv[1]为已存在的当前文件夹下的一个目录。注意:argv[1]必须为相对路径,不能为绝对路径,而且
*该路径必须和COPY可执行文件在同一个目录下,否则会运行出错!argv[2]可为相对路径或者绝对路径。
*/
#include<stdio.h>
#include<sys/types.h>
#include<sys/stat.h>
#include<unistd.h>
#include<dirent.h>
#include<stdlib.h>
#include<string.h>
#include<fcntl.h>

/*该函数为复制普通文件的具体操作*/
void copy_regular_file(char dirpath_from[],char dirpath_to[])
{
    int fd1,fd2,size;
    char buf[200]="";
    char dir1[255]="";
    char dir2[255]="";
   
    struct stat file;
    sprintf(dir1,"%s",dirpath_from);
    sprintf(dir2,"%s",dirpath_to);
    sprintf(dir2,"%s/%s",dir2,dir1);

    if(stat(dir1,&file)==-1)
    {
        printf("Can not get info of %s\n",dir1);
        exit(-1);
    }
    if((fd1=open(dir1,O_RDONLY))==-1)
    {   
        printf("Can not open file %s\n",dir1);   
        exit(-1);
    }
    if((fd2=creat(dir2,file.st_mode))==-1)//创建新的普通文件,并赋予相应的权限
    {   
        printf("Can not open file %s\n",dir2);   
        exit(-1);
    }
    while((size=read(fd1,buf,200))!=0)
        if(write(fd2,buf,size)!=size)
            printf("Write error!\n");
    close(fd1);close(fd2);
    return ;
}
/* 该函数为复制主体,同时也是一个递归函数。
     它对dirpath_from进行判断,判断其是目录文件还是普通文件,如果是普通文件,则执行相应的操作,马上返回;否则递归执行copy这个函数
*/
DIR *copy(char dirpath_from[],char dirpath_to[])
{
    DIR *dirpointer;
    char path1[255]="";//对应dirpath_from
    char path2[255]="";//对应dirpath_to
    char path3[255]="";//临时的字符串
    struct dirent *direntp;
    struct stat info;

    strcpy(path1,dirpath_from);//备份dirpath_from,dirpath_to.
    strcpy(path2,dirpath_to);

    if(stat(dirpath_from,&info)!=-1)
    {
        if((info.st_mode&0170000)==0040000)//判断该文件为目录
        {   
            sprintf(path3,"%s/%s",dirpath_to,dirpath_from);
            if(mkdir(path3,0777)==-1)
                        {
                printf("can not creat dir %s\n",path3);
                                 exit(-1);
                        }
            if((dirpointer=opendir(dirpath_from))==NULL)
            {
                printf("Can not open dir %s\n",dirpath_from);
                exit(-1);
            }
            while((direntp=readdir(dirpointer))!=NULL)
            {
                if(strcmp(direntp->d_name,".")==0||strcmp(direntp->d_name,"..")==0)
                        continue;
                sprintf(dirpath_from,"%s/%s",dirpath_from,direntp->d_name);           
                copy(dirpath_from,dirpath_to);//递归入点。。。
                sprintf(dirpath_from,"%s",path1);
            }   
        }   
        else //判断该文件为普通文件
        {
            copy_regular_file(dirpath_from,dirpath_to);
        }
    }
    strcpy(dirpath_from,path1);//还原dirpath_from,dirpath_to
    strcpy(dirpath_to,path2);
   
    return dirpointer;
}
int main(int argc,char **argv)
{
    DIR *dirp;
    char path1[255]="";
    char path2[255]="";
    sprintf(path1,"%s",argv[1]);
    sprintf(path2,"%s",argv[2]);
    if(argc<3)
    {
        printf("Please check the usage...\n");
        exit(-1);
    }
    dirp=copy(path1,path2);
    closedir(dirp);
    return 0;
}

另一个:

#include <stdio.h>
#include <dirent.h>

#include <sys/stat.h>
#include <stdlib.h>

int main(int argc, char *argv[])
{
 printf("cpd tool, Tommy jiang@2007.\n\n");
 if(argc != 3)
 {
  printf("Usage : cpd SOURCEIDR DESTDIR.\n");
  printf("Example : cpd /webs /mnt/sda1.\n\n");
  return 0;
 }
 FILE *fd1;
 FILE *fd2;
 int size = 0;
 
 DIR *dp;
 struct dirent *entry;
 struct stat statbuf;
 dp = opendir(argv[1]);
 chdir(argv[1]);
 char buf[1024];
 char name[256];
 memset(name, 0, 256);
 
 while((entry = readdir(dp)) != NULL)
 {
  lstat(entry->d_name, &statbuf);
  if(S_ISDIR(statbuf.st_mode))
   continue;
  fd1 = fopen(entry->d_name, "r");
  strcpy(name, argv[2]);
  strcat(name, "/");
  strcat(name, entry->d_name);
  printf("name = %s\n", name);
  fd2 = fopen(name, "w");
  while((size = fread(buf, 1, 1024, fd1)))
   fwrite(buf, 1, size, fd2);
  memset(name, 0, 256);
  fflush(fd2);
  sleep(1);
 }
 fclose(fd1);
 fclose(fd2);
 chdir("..");
 closedir(dp);

再一个:

#include "unistd.h"           //所需头文件定义
#include "string.h"
#include "dirent.h"
#include "utime.h"
#include "stdio.h"
#include "sys/types.h"
#include "sys/stat.h"
#include "fcntl.h"
#define MAX_PATH 1024 // 定义最大路径长度
void copy_data(char* spath,char* dpath)     //复制一个文件
{
    int nbyte ;                         //读出n个字节
    int pDir_s,pDir_d ;                //源文件句柄pDir_s, 目标文件句柄pDir_d
    char buf[BUFSIZ] ;                 //文件内容缓冲区
        struct stat file_stat ;           //文件属性 file_stat
    struct utimbuf mod_time;         //文件时间属性
        stat(spath,&file_stat) ;         //读取源文件属性
    if((pDir_s=open(spath,0)) == -1)     //打开源文件
    {
            printf("无法打开文件 %s,权限不足!\n",spath) ; //源文件不可读
        exit(0);
    }
    pDir_d=creat(dpath,0777);                    //创建一个目标文件,可读可写,可执行
    while((nbyte = read(pDir_s,buf,BUFSIZ)) > 0)        //从源文件读取内容,写入目标文件
    {
            if(write(pDir_d,buf,nbyte) != nbyte)     
           {
            printf("写数据出现异常错误!\n") ;     //写数据出错,退出
                        exit(0);
            }
    }
    mod_time.actime = file_stat.st_atime ;            //修改目标文件时间属性,保持和源文件一致
        mod_time.modtime = file_stat.st_mtime ;
        utime(dpath,&mod_time) ;
        chmod(dpath,file_stat.st_mode);                   //修改目标文件权限,保持和源文件一致
    close(pDir_s) ;                                   //关闭文件句柄
    close(pDir_d) ;
}
void mycp(char* source,char* des)              //拷贝一个目录,以及目录下子目录和相应的文件
{
    struct dirent* ent = NULL;         //定义目录属性dirent
    struct utimbuf mod_time;                //定义目录时间属性变量
    char spath[MAX_PATH] = "", dpath[MAX_PATH] = "" ;    //源文件路径spath,目标文件路径dpath
        DIR *pDir;                              //句柄
    struct stat file_stat ;                 //文件或者目录属性变量file_stat
    strcpy(spath,source) ;                 
    strcpy(dpath,des) ;                   
    pDir=opendir(source);                  //打开当前目录
    while (NULL != (ent=readdir(pDir)))    //循环读取文件或目录属性,遍历文件夹
        {             
        if(strcmp(ent->d_name,"..")==0||strcmp(ent->d_name,".")==0) //遇到子目录'.'或父母录标记'..',继续
            continue ;
                    if (ent->d_type == 4)    //d_type = 4,表示当前为子目录  
                    {
                                strcat(dpath,"/");        
                strcat(dpath,ent->d_name) ;        //构建目标文件子目录路径
                strcat(spath,"/");
                strcat(spath,ent->d_name) ;        //构建源文件子目录路径
                                stat(spath,&file_stat);            //读取源文件子目录属性
                mkdir(dpath,0777);            //创建目标文件子目录,可读可写,可执行
                mod_time.actime = file_stat.st_atime ;  
                //修改目标子目录时间属性和源子目录时间属性保持一致
                                mod_time.modtime = file_stat.st_mtime ;
                mycp(spath,dpath);                 //递归拷贝子目录
                                chmod(dpath,file_stat.st_mode);    //修改目标子目录权限,保持和原子目录权限一致
                                utime(dpath, &mod_time) ;          //设置目标子目录时间属性,保持和原子目录一致
                                strcpy(dpath,des);                 //还原路径
                strcpy(spath,source) ;
                    }
                        else {                 //d_type != 4,是文件,调用copy_data直接拷贝
                                strcat(dpath,"/");                  //构建目标文件路径
                strcat(dpath,ent->d_name) ;
                strcat(spath,"/");                 //构建源文件路径
                strcat(spath,ent->d_name) ;
                copy_data(spath,dpath);            //拷贝一个文件
                                strcpy(dpath,des);                 //还原路径
                strcpy(spath,source);            
                     }
            }
}
int main(int argc,char* argv[])
{
    DIR *pDir;
    struct stat file_stat ;
    struct utimbuf mod_time;                //定义目录时间属性变量
    if(argc < 2) //必须有2个参数, 一个为源文件夹路径,一个为目标文件夹路径
    {
        printf("argument error!\n");
        return 0 ;
    }
    printf("Copy start!\n");     //提示开始copy
    if (pDir = opendir(argv[1])==NULL)
    {
        printf("The file you want to copy do not exist!\n");
        return 0;
    }
        stat(argv[1],&file_stat) ;   //读取原路径文件夹属性
        if(pDir = opendir(argv[2])==NULL);    //如果目标文件夹不存在,则新建目标文件夹
        mkdir(argv[2],file_stat.st_mode);
    mod_time.actime = file_stat.st_atime ;            //修改目标文件时间属性,保持和源文件一致
    mod_time.modtime = file_stat.st_mtime ;
    utime(argv[2], &mod_time) ;          //设置目标子目录时间属性,保持和原子目录一致
    mycp(argv[1],argv[2])         ;//完成copy的函数
    printf("Copy complete!\n") ;//提示完成copy

  

抱歉!评论已关闭.