日期:2014-05-16 浏览次数:21104 次
目的:由于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);
}
}