Linux_mycp
重新实现cp命令
-
利用POSIX API(文件操作也可以使用ANSI C标准I/O库)编程实现cp –r命令,支持将源路径(目录)中的所有文件和子目录,以及子目录中的所有内容,全部拷贝到目标路径(目录)中。
-
lUNIX/Linux中在shell中输入命令名(可执行文件名)来启动程序,在命令名(可执行文件名)之后可以跟随一系列字符串(通过空格分割),这些字符串就是命令行参数
cp [参数] <源文件路径> <目标文件路径>。
cp /usr/local/src/main.c /root/main.c(文件到文件复制)。
cp /usr/local/src/main.c /root (文件到目录复制)。
cp –r /usr/local/src /root(递归复制,用于目录到目录的复制)。
源代码为:
int filestate; //实际读取的长度
char outbuf[BUF_SIZE]; //一次复制的字符串缓冲区
void dircopy(char *s_dir, char *d_dir, char *path);
void createdir(char *s_dir, char *d_dir, struct stat statbuf);
void spilt(char *s, char **sp);
void get_path(char *x_path, char **sp, char **dp);
void filecopy(char * para_sourcefile,char * para_destfile,mode_t para_mode)
void filecopy(char * para_sourcefile,char * para_destfile,mode_t para_mode)
{
int infd, outfd;
outfd = open(para_destfile, O_CREAT | O_TRUNC | O_WRONLY, para_mode);
infd = open(para_sourcefile, O_RDONLY); //分别新建文件和打开源文件
do //进行复制操作
{
filestate = read(infd, outbuf, BUF_SIZE);
write(outfd, outbuf, filestate);
} while (filestate != 0);
close(outfd);
close(infd);
}
void get_path(char *x_path, char **sp, char **dp)
{
for (int j = 0; (sp[j] != NULL && dp[j] != NULL); j++)
{
if (strcmp(sp[j], dp[j]))
{
strcpy(x_path, sp[j]);
}
} //找到第一个不同的目录
}
void spilt(char *s, char **sp)
{
char *p = NULL;
int i = 0;
p = strtok(s, "/");
sp[i] = p;
i = i + 1;
while ((p = strtok(NULL, "/")) != NULL)
{
sp[i] = p;
}
}
void createdir(char *x_path, char *d_dir, struct stat statbuf)
{
char newdir[MAX_PATH] = {};
strcat(newdir, d_dir);
strcat(newdir, "/");
strcat(newdir, x_path);
//用于生成目录绝对路径
int i = mkdir(newdir, statbuf.st_mode); //生成目录
}
void dircopy(char *s_dir, char *d_dir, char *path) //绝对路径,相对路径。
{
DIR *sourcdir; //源目录流
sourcdir = opendir(s_dir);
if (sourcdir == NULL)
{
printf("源目录打开失败:%s,请检查参数%s\n", strerror(errno), s_dir);
}
else
{
struct stat statbuf;
stat(s_dir, &statbuf); //获取当前文件的状态结构
createdir(path, d_dir, statbuf);
struct dirent *currentdp;
while ((currentdp = readdir(sourcdir)) != NULL)
{
if (currentdp->d_type == DT_REG)
{
char destfile[MAX_PATH] = {}; //目标路径
char sourcefile[MAX_PATH] = {}; //源路径
char newdir[MAX_PATH] = {}; //新建目录
strcat(destfile, d_dir);
strcat(destfile, "/");
strcat(destfile, path);
strcat(destfile, "/");
strcat(destfile, currentdp->d_name);
//要生成文件的绝对路径
strcat(sourcefile, s_dir);
strcat(sourcefile, "/");
strcat(sourcefile, currentdp->d_name);
//源文件绝对路径
struct stat statbuf1;
stat(sourcefile, &statbuf1); //获取当前文件的状态结构
filecopy(sourcefile,destfile,statbuf1.st_mode);
}
else if ((currentdp->d_type == DT_DIR) && strcmp(currentdp->d_name, "..") && (strcmp(currentdp->d_name, ".")))
{
char sdir[MAX_PATH] = {};
strcat(sdir, s_dir);
strcat(sdir, "/");
strcat(sdir, currentdp->d_name); //获取要复制的源目录绝对路径
char x_path[MAX_PATH] = {};
strcat(x_path, path);
strcat(x_path, "/");
strcat(x_path, currentdp->d_name); //获取需要复制的目录相对路径
dircopy(sdir, d_dir, x_path);
}
}
}
closedir(sourcdir);
}
int main(int arg, char *argv[])
{
struct stat statbuf2;
stat(argv[1], &statbuf2);
//源文件/目录状态参数
struct stat statbuf3;
stat(argv[2], &statbuf3);
//目标文件/目录状态参数
if (arg != 3)
{
printf("命令格式为:mycp [源文件或目录] [目标文件或目录]\n");
}
//提示命令正确格式
else
{
DIR *destdir; //目标目录流。
if (S_ISDIR(statbuf2.st_mode)) //源路径为目录时的操作
{
if (!S_ISDIR(statbuf3.st_mode))
{
printf("参数错误,找不到目标目录 %s\n", argv[2]);
exit(0);
}
else
{
char para_s[MAX_PATH] = {};
char para_d[MAX_PATH] = {};
strcpy(para_s, argv[1]);
strcpy(para_d, argv[2]); //字符串分隔函数传参,防止传址调用改变源值
char *sp[MAX_PATH] = {NULL};
char *dp[MAX_PATH] = {NULL}; //存放分隔的字符串,路径深度为MAX_PATH
spilt(para_s, sp);
spilt(para_d, dp);
char x_path1[MAX_PATH] = {};
get_path(x_path1, sp, dp);
printf("进入目录递归复制...\n");
dircopy(argv[1], argv[2], x_path1); //调用目录复制函数
printf("已将源目录 \"%s\" 递归复制到目标目录 \"%s\" 下\n", argv[1], argv[2]);
}
}
else if (S_ISREG(statbuf2.st_mode))
{ //源路径为普通文件时的操作。
if (!S_ISDIR(statbuf3.st_mode))
{ //目标路径不是目录
filecopy(argv[1],argv[2],statbuf2.st_mode);
printf("已将源文件 \"%s\" 复制到目标文件 \"%s\" \n", argv[1], argv[2]);
}
else
{ //目标路径是目录
destdir = opendir(argv[2]);
if (destdir == NULL)
{
printf("目的目录打开失败:%s,请检查参数%s", strerror(errno), argv[2]);
}
else
{
char destfile[MAX_PATH] = {}; //存放目的文件路径名,将目录和文件名拼接。
strcat(destfile, argv[2]);
strcat(destfile, "/");
char *temp = NULL;
temp = basename(argv[1]);
strcat(destfile, temp);
filecopy(argv[1],destfile,statbuf2.st_mode);
closedir(destdir);
printf("已将源文件 \"%s\" 复制到目标目录 \"%s\" 下\n", argv[1], argv[2]);
}
}
}
else
{
printf("参数错误,找不到源文件或目录: %s\n", argv[1]);
exit(0);
}
}
return (0);
}
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 VincentVan!
评论