1 不带缓冲的I/O——open read write lseek close
1 不带缓冲的I/O——open read write lseek close
1.1 不带缓冲:
文件的读写需要通过系统调用 调用内核的VFS来完成,所以在用户层和内核层的数据传输过程中可以使用缓冲区来暂存数据。这一章节所讲的函数都是在进程和内核之间没有使用缓冲区的,如果想使用缓冲区需要程序员自己实现。标准I/O库,stdio.h中用于文件读写的接口里面,已经自己实现了在用户和内核交换数据时的缓冲区。
1.2 文件描述符(FD)
INT类型。进程通过文件描述符来标识打开的文件。open返回的是fd;read write lseek close都需要给定要操作的文件的fd。这是根据内核实现而存在的一个概念,在内核中,为每个进程创建的数据结构里,task_struct进程描述符里,有一个列表是打开文件的描述符表,通过fd链接描述文件的数据结构。对于打开的文件,可以有多个文件描述符。
1.3文件状态标志
指进程对打开的文件可以执行什么操作:读、写、执行、截断(将文件大小设为0)、追加(写时从文件末尾开始)。文件状态标志规定了进程可以对文件执行的操作。在执行写操作时会检查文件状态标志是否有写权限,如果没有,则执行失败。
1.4文件偏移量
对于打开的文件,使用文件偏移量来记录当前位于文件的什么位置,相当于编辑器中的Cursor。
可以使用lseek设置文件偏移量,lseek返回当前的文件偏移量。
2 对内核行为的控制——dup fcntl sync
2.1文件描述符 dup
我们可以使用dup为打开的文件创建新的文件描述符,dup2(int old_fd, int new_fd)指定新创建的文件描述符。对于每一个进程,内核会为自动为他打开3个文件描述符 0 1 2,分别对应标准输入,标准输出,标准出错文件,至于这三个文件对应的值,和程序的运行环境有关,当进程是通过shell创建,标准输入输出就对应差shell终端。文件描述符可以在父子进程间共享,对于文件描述符有一个标志FD_CLOEXEC,可以设置文件描述符在子进程中是否自动关闭。
2.2文件状态标志 fcntl
我们可以使用fcntl获取文件状态标志F_GETFL、设置文件状态标志F_SETFL、复制文件描述符F_DUPFD(同上)、设置文件描述符F_SETFD、获取文件描述符F_GETFD、获取文件所属进程F_GETOWN、设置文件所属进程F_SETOWN、设置子进程中关闭F_DUPFD_CLOEXEC。
2.3文件同步 sync
文件一般是存放在磁盘,从磁盘到内核,操作系统会实现一定的缓存(VFS虚拟文件系统),所以数据不会马上同步到磁盘,可以调用sync fsync fdatasync将内核中缓存的脏数据同步到磁盘上。
注意
Shell中使用 > < >> << >& <&对输入输出进行重定向,就是通过进程 0 1 2 文件描述符的重新设置实现的。