Linux中的文件描述符

目录

文件描述符

 系统调用 open

 为什么fd从3开始呢?

 为什么是0,1,2,3...呢?

文件描述符分配规则 

系统调用 close

系统调用 wirte

系统调用 read


文件描述符

在了解文件描述符之前,先了解关于操作文件的系统调用,C语言中的fwrite,fread等等对文件操作的函数不是系统调用,而是C语言对系统调用做的封装。

语言为什么对系统调用封装?

1.原生的系统接口,使用成本较高

2.不同系统系统接口不同,直接使用接口,语言不具备跨平台性

什么是跨平台性?

C语言穷举了所有OS系统的底层接口并进行条件编译去封装不同系统的系统调用,就让C语言写的程序在不同的OS下都能正常编译运行,就称C语言具有跨平台性。

 系统调用 open

参数含义是:open(文件路径,打开方式,权限) 

参数flag表示打开方式,用宏传递,有O_RDONLY只读,O_WRONLY只写,O_RDWR读写三者取一,可加O_CREAT,O_TRUNC等,添加参数时用 | 的方式,因为系统调用传递标记位,是位图结构来传递的,简单来说不同的比特位具有不同的含义,或上不同的宏就是给不同位标记。

参数mode表示权限传递八进制数字,比如0666就可以了,如果要防止系统默认权限掩码影响,可以先调用umask函数修改权限。

返回值:返回文件描述符,-1返回值代表错误

使用示例:

输出:

 为什么fd从3开始呢?

因为0表示标准输入,1表示标准输出,2表示标准错误,当程序运行的时候,这三个文件已经被默认打开了,在C语言封装的结构体FILE中就有fileno成员就是表示文件描述符,比如下面代码输出:

 为什么是0,1,2,3...呢?

内核中用struct file结构体描述被打开的 文件(被打开的文件在内存中),进程pcb中有struct files_struct *files指针,指向描述进程打开文件的结构体,结构体中有struct file*fd_array[]指针数组存放指针,指针指向内核打开的文件,内核打开的文件被OS用链表维护起来。

从内核代码可以看到:

PCB中的files_struct:

files_struct中的文件指针数组:

 转到file的定义看到address_space:

其内部封装了文件的缓冲区:

 

上述内容画图理解下:

 

文件描述符分配规则 

从头遍历fd_array[]数组,找到一个最小的没有被使用的下标,比如关闭1号文件,打开新文件的文件描述符是1,往1文件中打印则会往新文件打印,先写到了缓冲区(语言级别)中 ,加\n也不刷新,因为写到磁盘的刷新策略是全缓冲,所以程序运行中除非强制刷新否则不刷新,程序退出会刷新。

使用系统调用dup2也可以完成上述的重定向操作,拷贝文件描述符对应的内容(本质是拷贝内核文件结构体指针),最终指向同一个文件 

注意:int dup2(int oldfd,int newfd) ,是将oldfd的内容拷贝到newfd,最后只剩oldfd,往newfd输出就会输出到oldfd文件,这就是输出重定向。

系统调用 close

函数原型:int close(int fd),参数就是要关闭的文件的文件描述符

注意,这里的关闭是进程关闭了文件,管理文件结构体的释放是OS的工作,文件内核结构中用计数器存储文件被打开的次数,进程关闭只需将指针数组对应下标内容改成NULL,并将计数器--即可。

系统调用 wirte

从buf中写入fd文件中,写入count字节,返回值类型是ssize_t表示有符号整数,写入失败就返回-1,写入成功就返回写入的个数。

系统调用 read

 返回值

>0,返回读取个数

=0 表示读取到了EOF

<0 读取失败

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值