Linux下自己实现cp命令
在Linux环境下,拷贝文件常用指令是cp,例如cp a.c b.c 就是将a.c的文件拷贝成名叫b.c的文件,那么cp 命令是怎么实现的呢,在此之前,先补充一个知识点。带参数的main函数在以往的编程中,我们的main函数一般写成以下形式:int main()或int main(void)括号中是空的或者有“void”,表示main函数没有...
在Linux环境下,拷贝文件常用指令是cp,例如cp a.c b.c 就是将a.c的文件拷贝成名叫b.c的文件,那么cp 命令是怎么实现的呢,在此之前,先补充一个知识点。
带参数的main函数
在以往的编程中,我们的main函数一般写成以下形式:
int main()
或
int main(void)
括号中是空的或者有“void”,表示main函数没有参数,调用main函数时不用给出实参。
但是有些情况下,main函数可以有参数,即int main(int argc,char *argv[ ])
其中argc和argv就是main函数的形参,他们是程序的“命令行参数”,其中argc(arguement count的缩写,表示参数个数),argv(arguement vector的缩写,表示参数向量),它是一个指针数组,数组的每个元素都是指针,指向命令行中的字符首地址。第二个参数char *argv[ ]也可替换成char **argv,它是一个指向指针的指针,同样能达到相同的效果。
注意:在使用带参数的main函数时,第一个形参必须是int型,用来接收形参个数,第二个参数必须是字符指针数组,用来接收从操作系统命令行传来字符的地址。
从上图中可以看出,cp指令使用时,首先给出cp命令,然后将源文件a.c复制成目标文件b.c,因此一共有3个参数,即argc的值为3。argv里面共有三个地址,argv[0]指向cp,argv[1]指向a.c地址,argv[2]指向b.c地址。
#include<stdio.h>
int main(int argc,char **argv)
{
printf("total parameters is :%d\n",argc);
printf("No.1 parameter is %s\n",argv[0]);
printf("No.2 parameter is %s\n",argv[1]);
printf("No.3 parameter is %s\n",argv[2]);
return 0;
}
在以上测试程序中,我们使用了带参数的main函数,分别验证其每个参数。
若采用以往的方式运行此段代码可以看到,当我们只给出./a.out一个参数指令时,argc的值为参数个数1,argv[0]也是我们的第一个命令行参数。
若我们给出完整的参数指令,就可以看到argc参数个数为3,第一个命令行参数argv[0]指向./a.out,第二个命令行参数argv[1]指向src.c,第三个命令行参数argv[2]指向des.c
cp命令的实现:
有以上的铺垫以后,我们先来分析以下文件是如何从源文件复制到目标文件的。其基本原理也是基于文件操作的相关指令,大致步骤如下:
1.打开被复制的源文件src.c
2.读取源文件src.c中的内容到读取缓冲器readBuf中
3.打开或者创建一个目标文件src.c,该文件是用于将复制的内容写入的地方
4.将读取缓冲器readBuf中的内容写入到目标文件src.c中
5.关闭源文件和目标文件,防止文件受损
在以上步骤中,相关的文件操作包括文件的打开open,文件的读取read,文件的写入write,文件的关闭close。
基于以上原理,便可用程序表述出来如下:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include<stdio.h>
#include<stdlib.h>
#include <unistd.h>
#include<string.h>
int main(int argc,char **argv)
{
int fdSrc;
int fdDes;
char *readBuf=NULL;
if(argc!=3){
printf("param error\n");
exit(-1);
}
fdSrc=open(argv[1],O_RDWR);
int size=lseek(fdSrc,0,SEEK_END);
readBuf=(char *)malloc(sizeof(char)*size+8);
lseek(fdSrc,0,SEEK_SET);
int n_read=read(fdSrc,readBuf,size);
fdDes=open(argv[2],O_RDWR|O_CREAT|O_TRUNC,0600);
int n_write=write(fdDes,readBuf,strlen(readBuf));
close(fdSrc);
close(fdDes);
return 0;
}
代码分析:在以上代码中,我们定义了两个文件描述符,分别是fdSrc源文件文件描述符,fdDes目标文件描述符。
1.首先判断用户给的参数个数是否是3个,若参数个数不对,则直接退出程序。
2.满足条件后,以可读可写的方式打开argv[1]指向的源文件Src.c,并获取源文件的文件描述符。
3.打开以后,读取文件描述符为fdSrc的源文件,将读取到的size大小的内容存放到读取缓冲器readBuf中,其中size大小可采用lseek的返回值来获取,readBuf存储空间的大小也由size的大小来决定。(注意:在读取以后光标移动到了文件末尾,再次读取时会从末尾开始造成读取为空,因此用lseek函数及时将光标移到文件头开始的地方)
4.读取源文件中的内容以后,打开目标文件,其中argv[2]指向文件描述符为fdDes的目标文件,若目标文件不存在则执行O_CREAT创建目标文件,若目标文件中在之前已有内容存放,则执行O_TRUNC去打开文件,并将其长度截短为0。
5.打开或创建目标文件以后,将我们从源文件读取并缓存到读取缓冲器readBuf中的内容写入到目标文件中。
6.关闭源文件和目标文件。
在gcc编译时将生成的执行文件命名为mycp
在执行时,共有三个参数,argv[0]为./mycp参数指令,argv[1]指向源文件demo13.c,即被复制的文件,argv[2]指向目标文件new.c,即被粘贴内容的文件。在运行后便可看到新生成的new.c文件,该文件内容是复制demo13.c的内容,这样我们自己的mycp复制指令就完成了。
更多推荐
所有评论(0)