日期:2014-05-16 浏览次数:20930 次
目的:由于linux下不提供拷贝文件或者目录的函数,很不方便!因此,提供一个封装的函数实现拷贝文件或者目录(带目录内容),实现类似cp -r 的功能,支持相对路径和绝对路径输入。
申明:代码不代表最优的实现,经初步测试没有问题,如有BUG自行修改!
#include <stdio.h> #include <unistd.h> #include <errno.h> #include <dirent.h> #include <sys/stat.h> #include <string.h> int CopyFileExt(char* dest,char* src); int main(int argc,char** argv) { /* int ret=0; ret = unlink("/home/caojianping/caotest"); printf("unlink return %d\n",ret); printf("ERROR:%s\n",strerror(errno)); DelFile("/home/caojianping/caotest"); */ if(argc != 3) { printf("Usage: copy dest src\n"); return -1; } CopyFileExt(argv[1],argv[2]); return 0; } // 目的和源可以是目录也可以是文件 // dest == 文件, src == 文件, 删除dest文件,拷贝src文件到dest文件 // dest == 目录, src == 文件, 拷贝文件到dest目录下,如有同名文件,覆盖之 // dest == 目录, src == 目录, 拷贝src目录内容到dest目录下作为子目录(包括其内容) // dest == 文件, src == 目录, 删除dest文件,拷贝src目录到dest命名的目录 // 返回值:0代表 OK,<0 出错 int CopyFileExt(char* dest,char* src) { struct stat statbuf; struct dirent *dirp; DIR *dp; int ret; int destFile; // 目标是文件标志 0表示目录,1表示文件 int srcFile; // 源是文件标志 0表示目录,1表示文件 char destFull[256]; //存储全路径 char srcFull[256]; //存储全路径 // get the fullpath if(dest[0]!='/') { getcwd(destFull,sizeof(destFull)); strncat(destFull,"/",sizeof(destFull)); strncat(destFull,dest,sizeof(destFull)); } else { strncpy(destFull,dest,sizeof(destFull)); } if(destFull[strlen(destFull)-1] == '/') // 去掉路径后缀 { destFull[strlen(destFull)-1] = '\0'; } if(src[0]!='/') { getcwd(srcFull,sizeof(srcFull)); strncat(srcFull,"/",sizeof(srcFull)); strncat(srcFull,src,sizeof(srcFull)); } else { strncpy(srcFull,src,sizeof(srcFull)); } if(srcFull[strlen(srcFull)-1] == '/') // 去掉路径后缀 { srcFull[strlen(srcFull)-1] = '\0'; } if(lstat(destFull,&statbuf) < 0) { return -1; } if(S_ISDIR(statbuf.st_mode)== 0) { destFile=1; // file } else { destFile=0; // directory } if(lstat(srcFull,&statbuf) < 0) { return -1; } if(S_ISDIR(statbuf.st_mode)== 0) { srcFile=1; // file } else { srcFile=0; // directory } // src is file if(srcFile) { FILE *fpdest; FILE *fpsrc; if(!destFile) { char destpath[256]; strncpy(destpath,destFull,255); char *truename = strrchr(srcFull,'/'); if(truename) { strncat(destpath,truename,255); } fpdest = fopen(destpath,"w"); } else { fpdest = fopen(destFull,"w"); } if(fpdest==NULL) { return -2; } fpsrc = fopen(srcFull,"r"); if(fpsrc==NULL) { return -2; } //copy file char buf[1024]; int size; int offset=0; do { size = fread (buf,1,sizeof(buf),fpsrc); if(size > 0) { fwrite(buf,1,size,fpdest); } } while (!feof(fpsrc)); fclose(fpdest); fclose(fpsrc); } else // src is directory { if(destFile) // dest is a file, override it { remove(destFull); mkdir(destFull,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); } dp = opendir(srcFull); if(dp == NULL) { return -2; } char destpath[256]; strncpy(destpath,destFull,255); char *dirname = strrchr(srcFull,'/'); if(dirname) { strncat(destpath,dirname,255); } mkdir(destpath,S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH); // while((dirp = readdir(dp)) != NULL) { if(strcmp(dirp->d_name,".")==0 || strcmp(dirp->d_name,"..")==0) { continue; } char srcpath[256]; strncpy(srcpath,srcFull,255); strncat(srcpath,"/",255); strncat(srcpath,dirp->d_name,255); CopyFileExt(destpath,srcpath); } closedir(dp); } }