借鉴https://blog.csdn.net/lf_2016/article/details/54587020
系统调用:用户直接调用操作系统暴露出来的接口,这种方式成为系统调用。
文件I/O操作就是系统调用, man手册,man 2 就是查询系统调用API,
常用的API有open close read write lseek fcntl
库函数调用:对操作系统暴露出来的接口进行封装形成了库函数,提供给用户调用。
标准文件I/O操作就是库函数调用,man手册,man 3 就是查询库函数接口。
常见的标准库函数fopen fread fwrite
实际上库函数是对系统调用的一层封装,因此库函数对文件操作的时候,必然会引起系统调用。也就是说,库函数调用实际上是通过系统调用实现的。例如:C库函数fwrite就是通过write实现的。
库函数调用可以大大减少系统调用的次数,这是因为缓冲区技术。在用户空间和内核空间,对文件都使用了缓冲区,当内核缓冲区写满之后或写结束之后才将内核缓冲区内容写到文件对应的硬件媒介中。
#include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int open(const char *pathname,int flags,int perms); flags:O_RDONLY O_WRONLY O_RDWR O_CREAT 若文件不存在,则创建一个新的文件,并用第三个参数为其设置权限。 O_TRUNC 若文件已经存在,那么会删除文件中的全部原有数据,并且设置文件大小为0 O_APPEND 以添加方式打开文件 返回值:成功返回文件描述 失败返回-1 int fd; fd = open("test.txt",O_RDWR|O_CREAT|O_TRUNC); if(fd < 0) { perror("fail to open"); }
#include <unistd.h> int close(int fd); 返回值:成功返回0 失败返回-1
#include <unistd.h> ssize_t write(int fd,const void *buf,size_t count); 功能:像文件描述符fd所指向的文件中写入,从buf开始的缓冲区中count个字节 返回值:成功时返回写入的字节数(若为零则表示没有写入数据) 失败时返回-1,并设置errno为相应值。
#include <unistd.h> ssize_t read(int fd,void *buf,size_t count); 功能:从文件描述符fd中读取count字节的数据并放入buf开始的缓冲区中。 返回值:成功时返回读取到的字节数 失败时返回-1,并设置errno为相应值。
#include <sys/types.h> #include <unistd.h> off_t lseek(int fd, off_t offset, int whence); /** *offset:相对与基准点whence的偏移量,以字节为单位,正数表示向前移动,复数表示向后移动 *whence:SEEK_SET 文件的起始位置 SEEK_CUR 文件当前读写位置 SEEK_END 文件的结束位置 **/ 返回值:成功时,定位到文件当前读写位置 失败时,返回-1,并设置errno为相应值
#define OFFSET 10240 int read_len; lseek(fd,-OFFSET,SET_END); while((read_len = read(fd,buf,sizeof(buf))) > 0) //读多少,写多少 { write(fdd,buf,read_len); }
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。