一、open/read/write/close等文件相关系统调用
- open、read、write、close等系统函数称为无缓冲I/O(Unbuffered I/O)函数,用户程序在读写文件时既可以调用C标准I/O库函数,也可以直接调用底层的Unbuffered I/O函数.
那么在讨论Linux环境下基础IO函数前,我们先看看之间接触过的C标准I/O库函数
C标准I/O库函数
fopen(3)
调用open(2)打开制定的文件,返回一个文件描述符(一个int类型的编号),分配一个FILE结构体,其中包含该文件的描述符、I/O缓冲区和当前读写位置等信息,返回这个FILE结构体的地址。
fgetc(3)
通过传入的FILE 参数找到该文件的描述符、I/O缓冲区和当前读写位置,判断能否从I/O缓冲区读到下一个字符,如果能就直接返回该字符,否则调用read(2)把文件描述符传进去,让内核读取该文件的数据到I/O缓冲区,然后返回下一个字符。(对于C标准I/O 来说打开的文件由FILE 指针表示,对于内核来说,打开的文件由文件描述符标示,文件描述符从open系统调用获得,在使用read、write、close系统调用时都需要传文件描述符。)
- fputc(3)判断该文件的I/O缓冲区是否有空间再存放一个字符,如果有则直接保存在I/O缓冲区中并返回,如果I/O缓冲区中已满就调用write(2),让内核把I/O缓冲区的内容写回文件。
fclose(3)
如果I/O缓冲区中还有数据没写回文件,就调用write(2)写回文件然后再调用close(2)关闭文件,释放FILE结构体和I/O缓冲区。
而open、read、write、close等系统函数称为无缓冲I/O(Unbuffered I/O)函数,用户程序在读写文件时既可以调用C标准I/O库函数,也可以直接调用底层的Unbuffered I/O函数,那个各自使用场景是什么呢?
- 用Unbuffered I/O函数每次读写都要进内核,调一个系统调用比调一个用户控件的函数要慢很多,所以在用户程序开辟I/O缓冲区还是必要的,用C标准I/O库函数比较方便。
- 用C标准I/O库函数要时刻注意I/O缓冲区和实际文件有可能不一致,在必要时调用fflush(3)。
- UNIX的传统是Everything is a file(一切皆文件),I/O函数不仅可以读写文件还可以读写设备。在读写设备时通常是不希望有缓冲的。比如网络设置的读写就希望是实时读写。
- C标准库函数是C标准的一部分,而Unb