博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
初级文件IO——open打开文件成功后行为分析
阅读量:6611 次
发布时间:2019-06-24

本文共 2141 字,大约阅读时间需要 7 分钟。

前言

如果open打开失败的话(比如文件不存在就会导致失败),open啥也不会干就直接返回了。但是如果open将文件打开成功的话,open具体做了哪些事情呢?

open成功后行为

记录打开文件的信息

程序运行起来后就是一个进程了,OS会创建一个的结构体,记录进程运行时的各种信息,比如所打开文件的相关信息。

open将文件成功打开后,在task_struct中又会创建一些结构体(数据结构),用于记录当前进程目前所开文件的信息,后续所有的文件操作,都需要依赖于这些信息,其中就包括指向打开文件的文件描述符。

文件描述符表

申请内存空间

open函数会申请一段内存空间(内核缓存),后续读写文件时,用于临时缓存读写文件时的数据。

什么是缓存?

就是开辟的一段内存空间,比如char buf[100],这就是一段100字节的缓存空间,用于临时存放中转的数据。

为什么叫内核缓存?

open是OS所提供的系统函数,属于OS内核的一部分,所以open函数所开辟的缓存空间,就是内核缓存。

#include 
#include
#include
#include
#include
int main(void){ int fd = 0; fd = open("./file.txt", O_RDWR); if(-1 == fd) { printf("open fail\n"); return 0; } else { printf("open ok\n"); } char buf1[] = "hello world"; write(fd, (void *)buf1, 11); lseek(fd, 0, SEEK_SET); char buf2[30] = {
0}; read(fd, buf2, sizeof(buf2)); printf("buf2 = %s\n", buf2); close(fd); return 0;}

例子程序中,我定义了buf1和buf2这两个数组,这两个数组是我自己的应用程序定义的,因此就叫应用缓存。

open为什么要开内核缓存空间?

内存读写速度 > 磁盘读写速度的,有了在内存中开辟的内核缓存后,上层读写数据时,会直接读写缓存,速度会很快,至于缓存与磁盘上文件数据的交换,就留给下层去做,这样可以节省上层操作的时间。

注意:open时只是开辟了内核缓存空间,里面并没有数据,只有当进行读写数据时,才会缓存读写的数据。

读写时,缓存间数据的流动是怎样的?

详论文件描述符

什么是文件描述符

open成功就会返回一个非负整数(0、1、2、3...)的文件描述符,比如我们示例程序中open返回的文件描述符是3。文件描述符指向了打开的文件,后续的read/write/close等函数的文件操作,都是通过文件描述符来实现的。

文件描述符表与task struct关系

文件描述符池

每个程序运行起来后,就是一个进程,系统会给每个进程分配0~1023的文件描述符范围,也就是说每个进程打开文件时,open所返回的文件描述符,是在0~1023范围中的某个数字。

0~1023这个范围,其实就是文件描述符池。

1023这个上限可不可以改?

可以,但是没有必要,也不会介绍如何去改,因为一个进程基本不可能出现,同时打开1023个文件的情况,文件描述符的数量百分百够用。

open返回文件描述符规则

open返回文件描述符池中,当前最小没用的哪一个。进程一运行起来,0/1/2默认就被使用了,最小没被用的是3,所以返回3。如果又打开一个文件,最小没被用的就应该是4,所以open返回的应该是4。

文件关闭后,被文件用的描述符怎么办

会被释放,等着下一次open时,被重复利用。

open的文件描述符 与 fopen的文件指针

open

Linux 的系统函数(文件io函数)。open成功后,返回的文件描述符,指向了打开的文件。

fopen

C库的标准io函数 

#include 
FILE *fopen(const char *path, const char *mode);

fopen成功后,返回的是FILE *的文件指针,指向了打开的文件。

对于Linux的C库来说,fopen 这个C库函数,最终其实还是open函数来打开文件的。fopen只是对open这个函数做了二次封装。见下图

也就是说,fopen的文件指针,最终还是会被换成open的文件描述符,然后用于去操作打开的文件。

 

 

 

转载于:https://www.cnblogs.com/kelamoyujuzhen/p/9638710.html

你可能感兴趣的文章
Android中UI线程与后台线程交互设计的5种方法
查看>>
JDBC公共动作类
查看>>
poj 3013 Big Christmas Tree (dij+优先级队列优化 求最短)
查看>>
JUnit单元测试
查看>>
windows 获取以及更改CMD控制台编码[转]
查看>>
[logstash-input-file]插件使用详解
查看>>
Java RMI
查看>>
HDU 3103 Shoring Up the Levees(计算几何 搜寻区域)
查看>>
专车新规或下周发布,估计有大量司机流失
查看>>
spring mvc模拟用户增删改查以及登录和上传文件的相关流程
查看>>
Linux的软中断处理实现 【转】
查看>>
编译OpenCV文档
查看>>
Training (deep) Neural Networks Part: 1
查看>>
Python采用struct处理二进制
查看>>
【游戏】有趣的小游戏合集
查看>>
如何使用vim的帮助功能
查看>>
内容编码
查看>>
用纯css改变下拉列表select框的默认样式
查看>>
TypeScript之基本数据类型
查看>>
csipsimple 下载地址
查看>>