Linux中的文件描述符-创新互联

目录

创新互联建站是专业的柞水网站建设公司,柞水接单;提供成都网站设计、成都网站建设、外贸网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行柞水网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!

文件描述符

系统调用 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 读取失败

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


文章名称:Linux中的文件描述符-创新互联
本文链接:http://pwwzsj.com/article/hpsoo.html