文件描述符

2 篇文章 0 订阅

1、Unix把文件描述符0与进程标准输入关联,把1与标准输出关联,把2与标准错误关联。

2、POSIX.1标准中STDIN_FILENO=0,STDOUT_FILENO=1,STDERR_FILENO=2。包含在头文件<unistd.h>中。

3、文件操作方式,包含在<fcntl.h>中。

O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开
O_EXEC 只执行打开
O_SEARCH 只搜索打开(应用于目录)
O_APPEND 文件追加
O_CLOEXEC
O_CREAT 文件不存在则创建
O_DIRECTORY path必须是目录
O_EXCL 配合O_CREAT,文件存在报错
O_NOCTTY
O_NOFOLLOW 如果path引用的是一个符号连接,则出错
O_NONBLOCK
O_SYNC 使write等待物理I/O操作完成
O_TRUNC 将已存在文件长度截断为0
O_TTY_INIT 
3、open函数

 原型:int open(const char *path, int oflag, ...);

 path为文件路径,oflag为上面各参数的“或”运算结果;

4、openat函数:

 原型:int openat(int fd, const char *path, int oflag, ...);

5、open和openat函数返回的文件描述符一定最小的未用描述符数值。

6、create函数

 原型:int create(const char *path, mode_t mode);

 等效于open(path, O_WRONLY | O_CREAT | O_TRUNC, mode);

7、close函数

 原型:int close(int fd);

 关闭一个文件时,会释放该进程加在该文件上的所有记录锁。

8、lseek函数

 原型:off_t lseek(int fd, off_t offset, int whence);//返回新的文件偏移量。

 显式的为一个打开文件设置偏移量。whence表示从offset向后偏移量,可正可负。offset为SEEK_SET则从开始处算起,为SEEK_CUR则从当前位置算起,为SEEK_END则从文件尾算起。

9、read函数

 原型:ssize_t read(int fd, void *buf, size_t nbytes);

 返回:读到的字节数,如果已经在文件尾,则为0;

10、write函数

 原型:ssize_t write(int fd; const void *buf, size_t nbytes);

 返回:已写的字节数,出错返回-1;

11、I/O效率

 用read和write复制一个文件,每次复制的buf大小影响着效率,经测试,1-4096效率在提高,之后不变。

12、文件共享

 文件使用三种数据结构表示打开文件

 (1)每个进程在进程表中都有一个记录项,记录相中包含一张打开文件的文件描述符列表,每个描述符占用一项。

  a.文件描述符标志

  b.指向一个文件表项的指针

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

  a.文件状态标志(读、写、添写,同步、非阻塞等)

  b.当前文件偏移量

  c.指向该文件v-node的指针

 (3)每个打开文件有一个v-node,包含文件类型和对文件操作的各函数的指针,

大多数文件还包含了i-node,i-node包含了文件所有者、文件长度、文件在磁盘上实际位置指针等。


13、原子操作

 函数pread和pwrite:

  原型:ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);

 返回读到的字节数,出错返回-1,相当于调用lseek后调用read,原子

    ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);

  返回已写的字节数,出错返回-1,相当于调用lseek后调用write,原子

 创建文件open函数:

  在open函数中用O_CREAT和O_EXCL说明时,判断文件不存在即创建时是原子操作。

14、dup和dup2函数

原型:int dup(int fd);

  int dup2(int fd, int fd2);

返回:成功则返回新的文件描述符,失败返回-1

(1)用于复制一个现有的文件描述符,dup函数返回的一定是当前可用的文件描述符中最小的数值。

(2)dup2函数可以用fd2指定新描述符的值。如果fd2已经打开,则先关闭。如果fd=fd2,则返回fd2,而不关闭它。

(3)这两个函数返回的新文件描述符与fd共享同一个文件表项。

(4)新文件描述符的执行时关闭标志总是由dup函数清除。

(5)复制一个文件描述符的另一个方法是fcntl函数。

 dup(fd)等同fcntl(fd, F_DUPFD, 0);

 dup2(fd, fd2)等同于close(fd2) + fcntl(fd, F_DUPFD, fd2);后者两步操作,不是原子

15、sync、fsync、fdatasync函数

 原型:void sync(void);

  作用:将所有修改过的块缓冲区排入写队列,然后返回,不等待实际写磁盘操作结束。

 原型:int fsync(int fd);

  返回:成功返回0,出错返回-1

  作用:只对fd指定的文件起作用,并且等待写磁盘操作结束才返回;

   适用于数据库这样的应用程序,确保修改过的块立即写到磁盘上。

原型:int fdatasync(int fd);

  返回:成功返回0,出错返回-1

  作用:类似于fsync,但是只影响文件的数据部分。而fsync还会同步更新文件的属性。

16、fcntl函数

 原型:int fcntl(int fd, int cmd, ...);

  返回:成功,依赖于cmd,出错返回-1

  作用:改变已经打开文件的属性。

  ①复制一个已有的描述符 cmd=F_DUPFD或F_DUPFD_CLOEXEC

  ②获取/设置文件描述符标志 cmd=F_GETFD或F_SETFD

  ③获取/设置文件状态标志 cmd=F_GETFL或F_SETFL

  ④获取/设置一步I/O所有权 cmd=F_GETOWN或F_SETOWN

  ⑤获取/设置记录锁 cmd=F_GETLK、F_SETLK或F_SETLKW

 F_DUPFD:复制文件描述符fd。新文件描述符作为函数值返回,是尚未打开的文件描述符中最小的。

新描述符与fd共享同一个文件表项,但有自己的一套文件描述符标志。

F_DUPFD_CLOEXEC:复制文件描述符,设置与新描述符关联的FD_CLOEXEC文件描述符标志的值,

返回新文件描述符。

F_GETFD:返回fd的文件描述符标志,当前只定义了一个文件描述符标志FD_CLOEXEC。

F_SETFD:设置fd的文件描述符标志,新标志按第三个参数设置,整型值。

F_GETFL:返回fd的文件状态标志。

O_RDONLY 只读打开
O_WRONLY 只写打开
O_RDWR 读、写打开
O_EXEC 只执行打开
O_SEARCH 只搜索打开(应用于目录)
O_APPEND 追加写
O_NONBLOCK 非阻塞模式
O_SYNC 等待写完成(数据和属性)
O_DSYNC 等待写完成(仅数据)
O_RSYNC 同步读和写

 其中O_RDONLY、O_WRONLY、O_RDWR、O_EXEC、O_SEARCH并非各占一位,前三个取0/1/2,

因此需要先于屏蔽字O_ACCMODE取得访问位方式,然后与这5个值一一比较。

 F_SETFL:将文件状态标志设置为第三个参数的值(整型),可以是O_APPEND、O_NONBLOCK、O_SYNC、

O_DSYNC、O_RSYNC、O_FSYNC、O_ASYNC。

 F_GETOWN:获取当前接收SIGIO和SIGURG信号的进程ID或进程组ID。

 F_SETOWN:设置接收SIGIO和SIGURG信号的进程ID或进程组ID。正的arg表示指定一个进程ID,

负的arg表示指定一个|arg|的进程组ID。

17、ioctl函数

 ioctl一直是I/O操作的杂物箱。不能用本章的其他函数表示的I/O操作通常都能用ioctl表示。

终端I/O是使用ioctl最多的地方。

 原型:#include<unistd.h>

  #include<sys/ioctl.h>

  int ioctl(int fd, int request, ...);

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值