在Linux中,cp命令表示复制文件,我们既然要实现cp命令先来看一下它的用法,即cp+源地址+目的地址,中间用空格隔开。本文将分别用C语言的文件操作和Linux的系统IO来实现此功能。
标准IO实现cp:
1 #include <stdio.h>
2 #include <stdbool.h>
3 #include <stdlib.h>
4 #include <string.h>
5
6 int _size(const char *filename)
7 {
8 FILE *fp=fopen(filename,"rb");
9 if(fp==NULL)
10 {
11 perror("fopen");
12 return -1;
13 }
14 fseek(fp,0,SEEK_END);
15 int size=ftell(fp);
16 fclose(fp);
17 return size;
18 }
19
20 int main(int argc,const char* argv[])
21 {
22 if(argc!=3)
23 {
24 printf("错误使用cp命令,格式为cp + source + destination");
25 return 1;
26 }
27 FILE *src=fopen(argv[1],"rb");
28 if(src==NULL)
29 {
30 perror("fopen");
31 return 1;
32 }
33 FILE *dest=fopen(argv[2],"wb");
34 if(dest==NULL)
35 {
36 fclose(src);
37 perror("fopen");
38 return 1;
39 }
40
41 char buf[256];
42 int num=fread(buf,1,_size(argv[1]),src);
43 //printf("%d\n",num);
44 fwrite(buf,1,num,dest);
45
46 fclose(src);
47 fclose(dest);
48 return 0;
49 }
系统IO实现带覆盖检测的cp:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
int _size(const char *file)
{
FILE *fp=fopen(file,"rb");
if(NULL==fp)
{
perror("fopen");
return -1;
}
fseek(fp,0,SEEK_END);
int size=ftell(fp);
fclose(fp);
return size;
}
int main(int argc,const char* argv[])
{
if(argc!=3)
{
printf("请正确引用cp格式:cp + src + dest");
return 1;
}
int src=open(argv[1],O_RDWR);
if(src==-1)
{
perror("open");
return 1;
}
int exist=open(argv[2],O_RDONLY);
char select;
if(exist!=-1)
{
printf("该文件已存在,是否覆盖[y/n]:");
scanf("%c",&select);
close(exist);
}
int dest;
if(select=='y') dest=open(argv[2],O_TRUNC|O_RDWR);
else dest=open(argv[2],O_APPEND|O_RDWR);
char buf[256];
int num=read(src,buf,_size(argv[1]));
write(dest,buf,num);
close(src);
close(dest);
return 0;
}
上面的代码虽然写法不同但基本思路一致,都是借助读写函数把数据从源地址的文件拷贝到缓冲区中,再从缓冲区写入目的地址,核心思想就是利用main函数的两个参数来获取文件路径,从而可以使得读写操作更方便进行。
over