cp指令
Linux的cp指令就是复制文件:
cp: 拷贝(cp 拷贝的文件 要拷贝到的地址或文件),cp b.c test.c 将b.c拷成test.c的一个新文件
Linux 系统初识_mjmmm的博客-CSDN博客
实现思路
- 打开源文件
- 读文件内容到缓冲区
- 创建新文件
- 将读到的文件内容全部写入新文件
- 关闭两个文件(不能忘!)
在实现之前,要明确如何在Linux中写带参数的函数,之前都是不带参数,然后执行就是./a.out就完事了。
cp A.c B.c这个函数
- int argc: int型的argc变量代表的是参数的个数
- char **argv: char型的二级指针变量argv代表的是具体的参数值
小实验:
#include <stdio.h> 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; }
可见,这样写就可以实现带参数的函数输入,且由于argv是二级指针,所以任何一个参数还是一个单独的字符串
demo5.c:
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
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,并随便打点内容:
执行代码:
打开新的file2:
可见,内容和file1一摸一样,copy成功!
同时注意一个很神奇的现象,在上面代码执行的cmd截图中,源文件和目标文件的文件标识符竟然是一样的,原因是我在读取源文件所有内容了之后就立刻关闭了源文件,所以之后将相同的文件标识符赋给目标文件也不会有问题。
如果将“源文件关闭”的操作留在最后进行,那么文件标识符就会不同:
另外,如果可以在gcc的时候给执行文件取名,这样实现的效果就更像cp一点:
同时,在FILE文件夹里也可以看到mycp这个执行文件: