C实现
#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
return 0;
}