目录
一. 回顾上文
在前两篇文章中,我论述了Linux系统中关于文件基础IO的一些内容:
1.有关于文件方面的系统调用函数:open、write、read、close等函数,也有C语言库中的fopen、fclose、fputs、fprintf等对文件操作的函数,C语言库中的函数是对系统调用函数底层实现原理的封装和优化;
2.文件=内容+属性。我们使用的C函数接口对文件的操作只是对其内容进行增删改;而只有使用的chmod、chgrep命令才是对文件的属性操作。
3.此外了解了Linux下进程与被打开文件的映射关系和底层原理图,发现:进程的结构体中可以关联到文件描述符表的数组,该数组存放着该进程打开的所有文件描述符及其属性;
4.文件被进程打开,操作系统就要管理该文件,本着先描述再管理的理念,OS为管理每个所文件都创建了一个数据结构:struct file,里面涵盖了该文件的所有属性数据。而进程的结构属性中都会指向一个大结构体:struct file_struct(文件描述符表),里面存放着被进程打开的所有文件。采用一个指针数组将这些文件串起来。在指针数组struct file* fd_array[ ]里面的每个元素都是一个指针,指向各个文件的地址,根据指针就能很快很方便的找到这些文件,并对其进行操作。而这些元素的下标又称为文件描述符fd,fd的值根据数组的索引下标而定。
Linux底层进程和被打开文件的映射关系图:
Linux部分源代码示意图如下:
二.Linux下一切皆文件的核心理解
Linux下一切皆文件是指,Linux系统中的一切东西全都可以通过文件的方式进行访问或者管理。反过来说,任何被挂在系统中的东西,即使它们的本质并不是文件,也会被OS以文件的眼光来呈现。
比如:我们经常讲到的进程、磁盘显示器设备等,实际上都不是文件,但是用户可以以文件系统的规范去访问它,修改属性。
目录的特点就是该目录中包含了各个文件的文件名以及指向这些文件的指针,打开目录就等同于打开文件。
由上面第4点可知:任何一个被打开的文件,在内核中呈现的结构体对象是struct file类型。
举个例子:在OS中,我们假如对磁盘中的某一文件进行读写操作时,代码中会有系统调用open函数,它的返回值fd描述符会作为指针指向该文件,在进行文件修改操作的过程中,我们会通过进程PCB访问到struct file_struct,进而找到fd指向该文件的struct file结构体中的readp、writep函数指针调用磁盘中相应的读写函数完成修改。
所以修改文件并不是简单的以为打开文件、修改完内容、关闭文件就完事了。而是需要通过告知OS系统,让它帮你去调用各类指针、函数、结构成员等一系列操作才能完成。