【一天一个命令的实现】cp命令

163 阅读2分钟

参考:《Unix-Linux编程实践》

命令功能

cp能复制文件

cp origin.c dest.c

//origin.c 源文件
//dest.c 目标文件,如果不存在就创建,存在就覆盖。

原理

读源文件,创建/重写新文件。

涉及到的系统调用

创建/重写文件 creat

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
int creat(const char *pathname, mode_t mode);
    //如果文件已经存在,就会将内容清空

image.png

image.png

写文件 read

#include <unistd.h>
ssize_t  write(int  fd,  const  void *buf, size_t count);

image.png

image.png

改变文件的当前位置lseek

Unix每次打开一个文件都会保存一个指针来记录文件的当前位置。

当从文件读数据时,内核从指针所标明的地方开始,读取指定的字节,然后移动指针,指向下一个未读取的字节。写文件的操作也是类似的。

指针是与文件描述符相关联的,而不是与文件相关联。

#include <sys/types.h>
#include <unistd.h>
off_t lseek(int  fd,  off_t  offset, int whence);

image.png

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

关于BUFSIZ

定义

   stdio.h:
     #define BUFSIZ _IO_BUFSIZ
   libio.h:
     #define _IO_BUFSIZ _G_BUFSIZ
   _G_config.h:
     #define _G_BUFSIZ 8192

程序输出时,为减轻系统负担,可以先将需要输出的字符保存起来,即放入内存缓冲。当达到输出条件时:行缓冲遇到换行符,块缓冲遇到写满缓存,或用户强制fflush;才进行写文件动作。

BUFSIZ为系统默认的缓冲区大小。

为什么系统调用需要很多时间

image.png

应用缓冲技术

想法的伪代码

image.png

为什么不一次取一条:这样就会频繁的使用系统调用,那么大部分时间都耗在了用户态和内核态的切换上。

为什么不一次取完:内存可能开不出这么的空间,并且我可能只是要读一条数据,却将整个数据都读入内存,太憨憨。

内核缓冲技术

image.png