Unix文件I/O

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010772289/article/details/86697019

Unix文件I/O
本节描述的函数经常被称为不带缓冲的I/O.

1

#include <fcntl.h>

int open(const char *path, int oflag, ... /* mode_t mode */);
int openat(int fd, const char *path, int oflag, ... /* mode_t mode */);
int creat(const char *path, mode_t mode);
        返回值: 若成功,返回文件描述符; 若出错,返回-1

open一些重要的oflag参数:

  • O_RDONLY/O_WRONLY/O_RDWR
  • O_APPEND: 追加
  • O_CREAT | O_EXCL: 测试并创建文件的原子操作
  • O_TRUNC: 截断
  • O_DIRECTORY: 若path不是目录,则出错
  • O_NONBLOCK: 若path是一个FIFO、一个块特殊文件或一个字符特殊文件,后续I/O操作设置为非阻塞方式.
  • O_SYNC: 同步写(使每次write等待物理I/O操作完成)
#include <unistd.h>

int close(int fd);      返回值: 若成功,返回0; 若出错,返回-1
off_t lseek(int fd, off_t offset, int whence);

ssize_t read(int fd, void *buf, size_t nbytes);  返回值: 读到的字节数,若已到文件尾,返回0;若出错,返回-1
ssize_t write(int fd, const void *buf, size_t mbytes);   返回值: 若成功,返回已写的字节数;若出错,返回-1

一个进程终止时,内核自动关闭它所有的打开文件

lseek仅将当前的文件偏移量记录在内核中,它并不引起任何I/O操作.然后,该偏移量用于下一个读或者写操作.

2.文件共享

UNIX系统支持在不同进程间共享打开文件。

内核使用3种数据结构表示打开文件。
(1) 每个进程在进程表中都有一个记录项,记录项包含一张打开文件描述符表,每一项包含:

  • 文件描述符标志
  • 指向一个文件表项的指针

(2) 内核为所有打开文件维持一张文件表, 每个文件表项包含:

  • 文件状态标志(读、写、添写、同步和非阻塞)
  • 当前文件偏移量
  • 指向该文件v节点表项的指针

(3) 每个打开文件(或设备)都有一个v节点结构。v节点包含文件类型和此文件进行各种操作函数的指针。对于大多数文件,v节点还包含了该文件的i节点。这些信息是在打开文件时从磁盘上读入内存的,所以文件的所有信息都是可以可用的,如i节点包含了文件的所有者、文件长度、指向文件实际数据块在磁盘上所在位置等。
在这里插入图片描述
如图3-8,若两个独立进程各自打开了同一个文件,则两个进程都获得各自的一个文件表项,但只有一个v节点表项。两个进程都获得自己的文件表项,是因为这可以使每个进程都有它自己的对该文件的当前偏移量.
在这里插入图片描述

3.11 原子操作

  • 打开文件时设置O_APPEND
  • lseek与读写的原子操作: pread, pwrite
  • 测试文件是否存在和创建文件的原子操作: open函数设置O_CREAT和O_EXCL选项

原子操作: 指的是由多步组成的一个操作。如果该操作原子地执行,则要么执行完所有步骤,要么一步也不执行。

3

(1)下面两个函数都可用来复制一个现有的文件描述符

#include <unistd.h>

int dup(int fd);
int dup2(int fd, int fd2);

dup2可用于重定向。

(2) sysc,fsync和fdatasync

延迟写: 大多数磁盘I/O都通过缓冲区进行。向文件写入数据时,内核通常先将数据复制到缓冲区,然后排入队列,晚些时候再写入磁盘

为保证磁盘实际文件系统与缓冲区中内容的一致性,Unix系统提供了sync,fsync,fdatasync.

(3)fcntl
可以改变已经打开文件的属性,包括:

  • 复制一个已有的文件描述符
  • 获取/设置文件描述符
  • 获取/设置文件状态标志
  • 获取/设置异步I/O所有权
  • 获取/设置记录锁

(4) ioctl

(5) /dev/fd
/dev/fd目录下是0、1、2等文件。打开文件/dev/fd/n等效于复制描述符n(假定描述符n是打开的)

小结

因为read和write都在内核进行,所以这些函数为不带缓冲的I/O函数。

猜你喜欢

转载自blog.csdn.net/u010772289/article/details/86697019