自己实现Linux 的 cp指令

cp指令

Linux的cp指令就是复制文件:

cp: 拷贝(cp 拷贝的文件 贝到的地址或文件),cp b.c test.c 将b.c拷成test.c的一个新文件

Linux 系统初识_mjmmm的博客-CSDN博客

实现思路

  1. 打开源文件
  2. 读文件内容到缓冲区
  3. 创建新文件
  4. 将读到的文件内容全部写入新文件
  5. 关闭两个文件(不能忘!)

在实现之前,要明确如何在Linux中写带参数的函数,之前都是不带参数,然后执行就是./a.out就完事了。

cp A.c B.c这个函数

  • int argc: int型的argc变量代表的是参数的个数
  • char **argv: char型的二级指针变量argv代表的是具体的参数值

小实验:

#include 

int main(int argc, char **argv)
{
        printf("total param:%d\n",argc);
        printf("First param is:%s\n",argv[0]);
        printf("Second param is:%s\n",argv[1]);
        printf("Third param is:%s\n",argv[2]);

        return 0;

}

自己实现Linux 的 cp指令_第1张图片

可见,这样写就可以实现带参数的函数输入,且由于argv是二级指针,所以任何一个参数还是一个单独的字符串

demo5.c: 

#include 
#include 
#include 
#include 
#include 
#include 
#include 

int main(int argc, char **argv)
{
	int fd1; // file description
	int fd2;
	char *buf_read;

	if(argc != 3){
		printf("lack of param!\n");
		exit(-1);
	}

	fd1 = open(argv[1],O_RDWR);
	printf("srcfile:%s\n",argv[1]);

	if(fd1 != -1){
		printf("srcfile description = %d, open successfully!\n",fd1);
	}else{
		printf("fail to copy, original file doesnt exit!\n");
		exit(-1);
	}

	int size = lseek(fd1,0,SEEK_END); //使用lseek的光标返回值计算文件的大小!!
	lseek(fd1,0,SEEK_SET); //计算完之后要将光标回到开头!!!
	buf_read = (char *)malloc(sizeof(char)*size + 1);

	int count_read = read(fd1, buf_read, size);
    if(count_read != -1){
        printf("%d bytes data has been read, context:%s\n",count_read, buf_read);
    }else{
        printf("fail to read\n");
		exit(-1);
    }

	close(fd1);
	fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC, 0600);
	printf("desfile:%s\n",argv[2]);

	if(fd2 != -1){
         printf("desfile description = %d, open successfully!\n",fd2);
    }else{
         printf("fail to open desfile\n");
         exit(-1);
    }


	int count_write = write(fd2, buf_read, strlen(buf_read));
	if(count_write != -1){
		printf("%d bytes data has been written\n",count_write);
	}else{
		printf("fail to write\n");
		exit(-1);
	}

	close(fd2);
	printf("copy completed!\n");

	return 0;
}

其中,这两句代码很重要! 

int size = lseek(fd1,0,SEEK_END); //使用lseek的光标返回值计算文件的大小!!
lseek(fd1,0,SEEK_SET); //计算完之后要将光标回到开头!!!

并且注意

fd2 = open(argv[2],O_RDWR|O_CREAT|O_TRUNC, 0600);

对于目标文件的打开,一定要加上O_CREAT O_TRUNC因为复制文件的时候,目标文件常常是不存在的,所以可能需要创建,而如果目标文件名已经存在,那么通常希望是将原来的数据全部删除,替换成新复制的数据,而不是单纯的覆盖,这样会导致错误。

实现效果

创建一个file1,并随便打点内容:

执行代码:

自己实现Linux 的 cp指令_第2张图片

打开新的file2:

 

可见,内容和file1一摸一样,copy成功!

同时注意一个很神奇的现象,在上面代码执行的cmd截图中,源文件和目标文件的文件标识符竟然是一样的原因是我在读取源文件所有内容了之后就立刻关闭了源文件,所以之后将相同的文件标识符赋给目标文件也不会有问题。

如果将“源文件关闭”的操作留在最后进行,那么文件标识符就会不同:

自己实现Linux 的 cp指令_第3张图片

另外,如果可以在gcc的时候给执行文件取名,这样实现的效果就更像cp一点:

自己实现Linux 的 cp指令_第4张图片

同时,在FILE文件夹里也可以看到mycp这个执行文件:

 自己实现Linux 的 cp指令_第5张图片

你可能感兴趣的:(linux,运维,服务器,系统编程)