六 编写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要切换到用户模式,必须把堆栈和内存环境恢复成用户运行时的状态。运行环境的切换要消耗时间。