第2章 用户、文件操作与联机帮助:编写cp命令

博客介绍了编写cp命令的相关内容,包括cp命令的功能、创建/重写文件的方式及编写流程。还阐述了提高文件I/O效率的方法,即使用缓冲,分析了缓冲区大小对性能的影响,以及系统调用需要时间的原因,如执行权限转移和运行环境切换。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

六 编写cp(读和写)

1.cp命令能做什么

cp能够复制文件,典型用法如下:

cp source-file target-file

如果target-file所指定的文件不存在,cp就创建这个文件,如果已经存在就覆盖,target-file的内容与source-file相同。

2.cp命令是如何创建/重写文件的

(1)创建/重写文件

创建或重写文件的一种方法是使用系统调用函数creat,用法如下:

系统调用creat
目标创建/重写一个文件
头文件fcntl.h
函数原型int fd=creat(char* fname,mode_t mode)
fname文件名
mode访问模式
返回值-1:遇到错误 0:成功创建

creat告诉内核创建一个名为filename的文件,如果文件不存在,就创建它,如果已经存在,就把它的内容清空,把文件的长度设为0。

(2)写文件

用write系统调用向已打开的文件中写入数据

系统调用write
目标将内存中的数据写入文件
头文件unistd.h
函数原型ssize_t result=write(int fd,void* buf,size_t amt)
fd文件描述符
buf内存数据
amt要写的字节数
返回值-1:遇到错误 num_written:成功写入

write系统调用告诉内核将内存中指定的数据写入文件,如果内核不能写入或写入失败,返回-1,如果写入成功,返回写入的字节数。
有的系统对文件的最大尺寸有限制,或者磁盘空间接近满,在上述两种情况下,内核都会尽量将数据往文件中写,并将实际写入的字节数返回,所以调用write后都必须检查返回值是否与要写入的相同,如果不同,就要采取相应的措施。

3.如何编写cp

流程:从源文件中读取数据写入缓冲流,再将缓冲中的数据写入目标文件。下面为cp的第一个版本cp1:

/**cp1.c
 * version 1 of cp - uses read and write with tunable buffer size
 * usage:cp1 src dest
 */
 #include<stdio.h>
 #include<unistd.h>
 #include<fcntl.h>
 
 #define BUFFERSIZE 4096
 #define COPYMODE 0644
 
 void oops(char*,char*);
 int main(int argc,char* argv[])
 {
	 int in_fd,out_fd,n_chars;
	 char buf[BUFFERSIZE];
	 if(argc!=3)
	 {
		 fprintf(stderr,"usage:%s source destination\n",*argv);
		 exit(1);
	 }
	 if((in_fd=open(argv[1],O_RDONLY))==-1)
		 oops("Cannot open ",argv[1]);
	 if((out_fd=creat(argv[2],COPYMODE))==-1)
		 oops("Cannot create ",argv[2]);
	 while((n_chars=read(in_fd,buf,BUFFERSIZE))>0)
		 if(write(out_fd,buf,n_chars)!=n_chars)
			 oops("Write error to ",argv[2]);
	 if(n_chars==-1)
		 oops("Read error from ",argv[1]);
	 if(close(in_fd)==-1||close(out_fd)==-1)
		 oops("Error closing files","");
	 return 0;
 }
 
 void oops(char* s1,char* s2)
 {
	 fprintf(stderr,"Error: %s",s1);
	 perror(s2);
	 exit(1);
 }

编译后进行如下测试:
在这里插入图片描述

cmp没有给出任何提示,说明它们的内容完全相同。错误测试情况如下:
在这里插入图片描述

七 提高文件I/O效率的方法:使用缓冲

1.缓冲区的大小对性能的影响

缓冲区的大小对性能有很大的影响。大的缓冲区可以有效减少操作次数,系统调用需要时间,程序中频繁的系统调用会降低程序的运行效率。

2.为什么系统调用需要时间

当系统调用发生时,执行权限会从用户代码转移到内核代码,执行内核代码需要时间。
系统调用发生,运行内核代码时,CPU工作在管理员模式,对应于一些特殊的堆栈和内存环境,必须在系统调用发生时建立好。系统调用结束后,CPU要切换到用户模式,必须把堆栈和内存环境恢复成用户运行时的状态。运行环境的切换要消耗时间。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值