用Linux_C语言模拟CP命令,实现文件和文件夹的拷贝

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<dirent.h>//输出文件信息
#include<sys/stat.h>//判断是否目录
int is_dir(char* path){//判断是否是目录
	struct stat st;
	stat(path,&st);
	if(S_ISDIR(st.st_mode)){
		return 1;
	}
	else{
		return 0;
	}
}
/*字符串处理函数*/
int endwith(char* s,char c){//用于判断字符串结尾是否为“/”
	if(s[strlen(s)-1]==c){
		return 1;
	}
	else{
		return 0;
	}
}
char* str_contact(char* str1,char* str2){//字符串连接
	char* result;
	result=(char*)malloc(strlen(str1)+strlen(str2)+1);//str1的长度+str2的长度+\0;
	if(!result){//如果内存动态分配失败
		printf("字符串连接时,内存动态分配失败\n");
		exit(1);
	}
	strcat(result,str1);
	strcat(result,str2);//字符串拼接
	return result;
}
/*复制函数*/
void copy_file(char* source_path,char *destination_path){//复制文件
	char buffer[1024];
	FILE *in,*out;//定义两个文件流,分别用于文件的读取和写入int len;
	if((in=fopen(source_path,"r"))==NULL){//打开源文件的文件流
		printf("源文件打开失败!\n");
		exit(1);
	}
	if((out=fopen(destination_path,"w"))==NULL){//打开目标文件的文件流
		printf("目标文件创建失败!\n");
		exit(1);
	}
	int len;//len为fread读到的字节长
	while((len=fread(buffer,1,1024,in))>0){//从源文件中读取数据并放到缓冲区中,第二个参数1也可以写成sizeof(char)
		fwrite(buffer,1,len,out);//将缓冲区的数据写到目标文件中
	}
	fclose(out);
	fclose(in);
}
void copy_folder(char* source_path,char *destination_path){//复制文件夹
	if(!opendir(destination_path)){
		if (mkdir(destination_path,0777))//如果不存在就用mkdir函数来创建
		{
		    printf("创建文件夹失败!");
		}
	}
	char *path;
	path=(char*)malloc(512);//相当于其它语言的String path="",纯C环境下的字符串必须自己管理大小,这里为path直接申请512的位置的空间,用于目录的拼接
	path=str_contact(path,source_path);//这三句,相当于path=source_path
	struct dirent* filename;
	DIR* dp=opendir(path);//用DIR指针指向这个文件夹
	while(filename=readdir(dp)){//遍历DIR指针指向的文件夹,也就是文件数组。
		memset(path,0,sizeof(path));
		path=str_contact(path,source_path);
		//如果source_path,destination_path以路径分隔符结尾,那么source_path/,destination_path/直接作路径即可 
		//否则要在source_path,destination_path后面补个路径分隔符再加文件名,谁知道你传递过来的参数是f:/a还是f:/a/啊?
			char *file_source_path;
			file_source_path=(char*)malloc(512);
			if(!endwith(source_path,'/')){	
			file_source_path=str_contact(file_source_path,source_path);
			file_source_path=str_contact(source_path,"/");	
				}
		else{
			file_source_path=str_contact(file_source_path,source_path);
		}
		char *file_destination_path;
		file_destination_path=(char*)malloc(512);
		if(!endwith(destination_path,'/')){
			file_destination_path=str_contact(file_destination_path,destination_path);
			file_destination_path=str_contact(destination_path,"/");
		}
else{
			file_destination_path=str_contact(file_destination_path,destination_path);
		}
		//取文件名与当前文件夹拼接成一个完整的路径
		file_source_path=str_contact(file_source_path,filename->d_name);
		file_destination_path=str_contact(file_destination_path,filename->d_name);
		if(is_dir(file_source_path)){//如果是目录
			if(!endwith(file_source_path,'.')){//同时并不以.结尾,因为Linux在所有文件夹都有一个.文件夹用于连接上一级目录,必须剔除,否则进行递归的话,后果无法相像
				copy_folder(file_source_path,file_destination_path);//进行递归调用,相当于进入这个文件夹进行复制~
			}		
		}
		else{
			copy_file(file_source_path,file_destination_path);//否则按照单一文件的复制方法进行复制。
			printf("复制%s到%s成功!\n",file_source_path,file_destination_path);
		}
	}	
}
/*主函数*/
int main(int argc,char *argv[]){
	if(argv[1]==NULL||argv[1]==NULL){
		printf("请输入两个文件夹路径,第一个为源,第二个为目的!\n");
		exit(1);
	}
	char* source_path=argv[1];//取用户输入的第一个参数
	char* destination_path=argv[2];//取用户输入的第二个参数
	DIR* source=opendir(source_path);
	DIR* destination=opendir(destination_path);
	if(!source||!destination){
		//对单个文件进行拷贝
		int len;
		char buf[1024];
		FILE *in,*out;
		in=fopen(argv[1],"r+");
		out=fopen(argv[2],"w+");
		while(len=fread(buf,1,sizeof(buf),in))
		{
			fwrite(buf,1,len,out);
		}
		printf("复制%s到%s成功!\n",argv[1],argv[2]);
		return 0;
	}
	copy_folder(source_path,destination_path);//进行文件夹的拷贝
	return 0;

}


到此,程序写完,下一步就是编译运行了:

#gcc -o  copy  copy.c

你想把/mnt/yaffs/abc目录下的所有东西,拷贝到/share目录下

#./copy  /mnt/yaffs/abc   /share/abc

假设abc下有a.txt 、文件夹b、d.c;

那么命令执行完之后,在/share/abc下就有a.txt 、文件夹b、d.c了,而且文件夹b下的东西也会被拷贝过来

拷贝单个文件a.txt

  ./copy  /mnt/yaffs/abc/a.txt     /share/abc/a.txt


  • 4
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 6
    评论
### 回答1: cp命令Linux系统中常用的命令之一,用于复制文件或目录。要用C语言实现cp命令,需要使用系统调用函数来完成文件的读写操作。具体实现步骤如下: 1. 打开源文件和目标文件,使用open()函数,获取文件描述符。 2. 读取源文件的内容,使用read()函数,将读取的内容存储到缓冲区中。 3. 将缓冲区中的内容写入目标文件,使用write()函数。 4. 关闭源文件和目标文件,使用close()函数,释放文件描述符。 5. 处理错误情况,如文件打开失败、读写失败等。 需要注意的是,如果要复制目录,则需要使用递归函数来遍历目录中的所有文件和子目录,并逐一复制。同时,还需要处理文件权限、时间戳等信息的复制。 ### 回答2: 在Linux系统中,cp命令的作用是将一个文件复制到另一个文件或目录。一般情况下,我们使用cp命令进行文件的备份或复制,而在Linux系统中,cp命令实现是基于C语言的。以下是用C语言实现cp命令的方法: 在C语言中,可以使用文件操作函数来实现cp命令文件操作函数主要有fopen、fclose、fread、fwrite、fgetc等函数,它们可以实现文件的读和写。 首先,我们需要打开源文件和目标文件,使用fopen函数可以打开文件并返回文件指针,然后使用fread和fwrite函数来读取和写入文件。可以使用fgetc函数来逐步读取一个文件中的字符,并使用fwrite函数来逐个写入目标文件中。注意,在写入目标文件之前,我们需要先创建目标文件,可以使用fopen函数来创建目标文件并返回文件指针。 在实现cp命令时,必须要判断文件复制是否成功。可以使用feof函数来检查文件是否读取到了文件末尾,如果文件读取到了文件末尾,则表示文件已经读取完毕。可以使用ferror函数来检查是否有错误发生,例如文件不存在或无法读取文件等错误。 最后,完成文件复制后,我们需要关闭源文件和目标文件。可以使用fclose函数关闭文件并释放文件指针,以确保程序的执行效率和数据安全。 总之,用C语言实现cp命令需要掌握文件操作函数的使用,能够编写出安全、高效、可靠的文件复制程序。 ### 回答3: CP命令Linux系统的常用命令之一,它用于复制文件或目录。在Linux系统中,可以使用C语言实现CP命令。下面是一些关于如何使用C语言实现CP命令的基本步骤: 1. 引入必要的头文件 为了实现CP命令,需要引入一些必要的头文件,如<stdio.h>、<stdlib.h>、<unistd.h>、<string.h>等。这些头文件包含了一些常用的函数和操作系统相关的宏定义。 2. 获取源文件名和目标文件名 从命令行参数中获取源文件和目标文件名。一般来说,CP命令命令行参数有两个,第一个是源文件名,第二个是目标文件名。可以使用argc和argv[]来获取这些参数。 3. 打开源文件和目标文件 使用系统调用函数open()来打开源文件和目标文件。打开源文件时,需要使用只读模式,而打开目标文件时,需要使用写模式。如果目标文件已经存在,则需要进行覆盖处理。 4. 读取源文件内容并写入目标文件中 使用系统调用函数read()和write()来读取源文件的内容并写入到目标文件中。在读取和写入时,需要注意缓冲区的大小和残留部分的处理。 5. 关闭文件指针 在使用完文件后,需要使用系统调用函数close()来关闭文件指针。这个步骤非常重要,在使用完文件后,必须关闭文件以便释放系统资源。 以上就是使用C语言实现CP命令的基本步骤。当然,CP命令还有一些其他的功能,如递归拷贝目录、保留文件属性等,这些功能可以通过使用其他系统调用函数和自定义函数来实现

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值