Linux下cp命令模拟

学过Linux的都知道, cp命令是linux系统中的文件复制命令,它有很多的参数,提供了很强的功能。不仅可以进行文件的复制,而且还能复制整个目录。

下面利用文件I/O操作来模拟cp命令的单个文件复制与整个目录的复制功能.

用到的函数: 包括文件操作与文件I/O操作

 

cp命令模拟程序:

例如: 复制/etc/inittab到root目录下,可以用 ./cp  /etc/inittab /root/

                ./cp /root/dir  /boot/ 把root下的目录dir复制到boot下

./cp是编译生成的exe文件.

 

 

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <string.h>
#include <fcntl.h>

#include <unistd.h>
#include <dirent.h>
#include <stdlib.h>
#define SIZE 65536*1024
#define LENGTH 1024
char buffer[SIZE];//复制用的内存块
void cpdir( char* argv1,char* argv2);
int main(int argc,char*argv[]){
char* argvx=argv[1];
char str1[100];
strcpy(str1,argvx);

FILE* fp;
struct stat statbuf;
if(argc==1){
printf("%s/n", "cp: 缺少了文件操作数请尝试执行“cp --help”来获取更多信息。");
return 0;
}



else if(argc==3){

lstat(argv[1],&statbuf);//得到源文件的状态和属性信息
if(statbuf.st_mode&S_IFDIR){//如果是一个目录则进行相应的处理
//首先建立目标根目录
char* p1;
char *p;

p=strtok(argv[1],"/");
while(p!=NULL){
p1=p;
p=strtok(NULL,"/");
}

strcat(argv[2],p1);
int fdir=mkdir(argv[2],0664);//建立目标目录
if(fdir==-1){
perror("建立目标目录失败");
return 1;
}



char str2[100];
strcpy(str2,argv[2]);
cpdir(str1,str2);


}
//如果只是单个文件
else{
char a[10];
strcpy(a,argv[1]);
printf("%s/n","sssss");
char *p;
char *p1;//p1指向目标文件名
p=strtok(a,"/");
while(p!=NULL){
p1=p;
p=strtok(NULL,"/");
}
printf("%s/n",p1);
strcat(argv[2],p1);
printf("%s/n",argv[2]);
//建立目标文件
int f=open(argv[2],O_CREAT|O_RDWR,0664);
if(f==-1){
perror("建立目标文件");
return 0;
}
//读源文件到缓冲区内,先打开源文件,返回文件流指针
printf("%s/n",argv[1]);
fp=fopen(argv[1],"r");//以只读方式打开
if(fp==NULL){
perror("打开源文件");
return 1;
}

int realread=fread(buffer,LENGTH,SIZE/LENGTH,fp);//返回实际读文件到缓冲区的次数,每次读入的数据为length
if(realread<0){
perror("读源文件失败");
return 0;
}
fclose(fp);//关闭源文件流指针
//打开目标文件
fp=fopen(argv[2],"rw+");//以读写的方式打开目标文件
if(fp==NULL){
perror("打开目标文件失败");
return 1;
}

int realwrite=fwrite(buffer,LENGTH,SIZE/LENGTH,fp);//将缓冲区的内容读到目标文件中去
if(realwrite<=0){

perror("写目标文件失败");
return 1;
}

fflush(fp);//将缓冲区内的数据立即写到文件中去
fclose(fp);//关闭目标文件流指针




}

}




return 0;


}
//如果复制目录
void cpdir(char* argv1, char* argv2){
//一个整形参数,另一个是char型指针数组
//argv1里面存放的是源目录名,argv2里面存放的是目标路径名
printf("%s/n",argv1);
printf("%s/n",argv2);
struct stat statbuf;
DIR *dp;//定义一个目录流指针
FILE* fp;

struct dirent *entry;//定义一个指向目录流指针的下一个目录相关信息的结构体

if((dp=opendir(argv1))==NULL){
printf("%s/n","无法打开该目录");
return;
}

chdir(argv1);

while((entry=readdir(dp))!=NULL){
stat(entry->d_name,&statbuf);//判断一下子目录流指针所指向的是不是目录
printf("entry->d_name=%s/n",entry->d_name);

if(statbuf.st_mode&S_IFDIR){
printf("%s/n","dirrrrrr");
if(strcmp(entry->d_name,".")==0||strcmp(entry->d_name,"..")==0){

continue;//如果是当前目录或者是上一级的目录则不复制
}


char s[100];
strcpy(s,argv2);
strcat(s,"/");
strcat(s,entry->d_name);
int fdir= mkdir(s,0664);

//建立目录

if(fdir==-1){
perror("目标目录建立失败");
return;
}
cpdir(entry->d_name,s);

}
//else里面处理的是文件复制
else{
printf("%s/n","file=====");
printf("filename=%s/n",entry->d_name);
//得用非缓冲区I/O操作,系统调用提供的函数
char argv22[100];
strcpy(argv22,argv2);
strcat(argv22,"/");
strcat(argv22,entry->d_name);
// printf("argv2=%s/n",argv2);
// printf("%s/n",entry->d_name);
//printf("%s/n",argv22);
//建立目标文件
int f1=open(argv22,O_CREAT|O_RDWR,0664);
if(f1==-1){
perror("目标文件建立失败");
return ;
}
int f=0;
f=open(entry->d_name,O_RDONLY);//以只读的方式打开源文件
if(f==-1){
perror("源文件打开失败");
return;
}

int realread=read(f,buffer,SIZE);
if(realread>0){

int realwrite=write(f1,buffer,SIZE);//写到目标文件中去
if(realwrite<=0){
perror("写入失败");
return ;
}

}

close(f);//关闭源文件
close(f1);

}


}

chdir("..");
closedir(dp);//关闭子目录流指针


}

 

以上程序用到了文件操作的一些函数,如open,mkdir,unlink,readdir,opendir等 ,还用到了文件I/O操作的一些函数,如read,fread,write,fwrite,flush等。模拟了文件复制命令cp的部分功能。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值