扫二维码与项目经理沟通
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流
目录
创新互联建站是专业的柞水网站建设公司,柞水接单;提供成都网站设计、成都网站建设、外贸网站建设,网页设计,网站设计,建网站,PHP网站建设等专业做网站服务;采用PHP框架,可快速的进行柞水网站开发网页制作和功能扩展;专业做搜索引擎喜爱的网站,专业的做网站团队,希望更多企业前来合作!文件描述符
系统调用 open
为什么fd从3开始呢?
为什么是0,1,2,3...呢?
文件描述符分配规则
系统调用 close
系统调用 wirte
系统调用 read
在了解文件描述符之前,先了解关于操作文件的系统调用,C语言中的fwrite,fread等等对文件操作的函数不是系统调用,而是C语言对系统调用做的封装。
语言为什么对系统调用封装?
1.原生的系统接口,使用成本较高
2.不同系统系统接口不同,直接使用接口,语言不具备跨平台性
系统调用 open什么是跨平台性?
C语言穷举了所有OS系统的底层接口并进行条件编译去封装不同系统的系统调用,就让C语言写的程序在不同的OS下都能正常编译运行,就称C语言具有跨平台性。
参数含义是: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元起,快前往官网查看详情吧
我们在微信上24小时期待你的声音
解答本文疑问/技术咨询/运营咨询/技术建议/互联网交流