文件系统简单回顾

概念分辨

在讲文件系统的时候,硬盘肯定是绕不过的。首先需要理解一点,那就是硬盘中最小的单位是扇区,一个扇区是512字节,这是硬件上规定的,不会改变。

然后操作系统需要去读取硬盘上的内容,由于一个扇区其实是需要通过磁头去定位到其上面然后读取的,根据局部性原理,操作系统会多读几个连续的扇区,即一次性会读取多个扇区,称为

简单点就是扇区是硬盘上最小的单位,而块是操作系统眼里最小的单位。

iNode

所有的文件数据都是放到块里面的,而文件描述的信息(即元信息)则是存放在iNode里面。可以通过stat file来查看对应的inode信息。显然iNode记录了文件的字节数、所有者及权限、文件时间戳和链接数等。唯一注意的是,iNode它不存储文件名字,也就是无法根据iNode号码来确定文件名字。

系统在磁盘格式化的时候,会将硬盘自动分成两个区,一个是用来存放数据的、另外一个就是用来存放iNode的。可以通过df -i查看每个分区的iNode使用情况。而如何划分两个区的比例就是一个仁者见仁的问题了,因为如果小文件比较多,那么iNode应该多分配点;相反如果都是大文件,那么iNode区域应该小一点而数据区应该大一点,但是操作系统并不能知道未来,so。。。

一般一个inode的大小是256k,而它所包含的信息,其实根据iNode所能提供的信息反推应该很容易了,因为iNode需要通过指针指向最终的文件数据区域,而一个iNode又不是很大,所以会有类似多级页表的设计。

所以最终的文件其实是和iNode进行绑定的,而与文件名无关。系统打开一个文件,其实是通过文件名找到inode,在通过iNode找到对应的块,然后把对应的数据找出来。那么系统是如何知道文件名和iNode的映射关系的呢?就是通过所在文件的文件夹获取的。

文件夹

其实linux中并没有一个叫文件夹的东西,因为一切皆文件,本文只是因为文件夹比较容易表述。文件夹的内容其实非常简单,里面的内容其实就是文件-iNode的对应关系。

所以这里也可以很好理解目录的权限了。如果是可读,那么就可以读取到对应的文件-inode对应关系,那么就可以看到所有的文件。如果是可写,那么就是可以创建对应的映射关系(也就是可以进入到文件夹里创建文件、删除文件);如果可执行,那么就是可以进入该文件夹。

打开一个文件,操作系统做了什么

这个问题其实应该算在操作系统面试里面的,和打开一个网页底层发生了什么异样有异曲同工之妙。需要明确的一点是,一定是一个进程它打开文件,所以整个过程是这样子的:操作系统会维护一个自己打开的所有文件的表格,而这个表格是所有进程共享的。那么首先进程就会先去查看一下这个表格,看看这个自己希望打开的文件,在不在表格里面。如果在的话,那么只需要在进程自己的PCB里面(准确的说应该是PCB里面有一个指针指向的进程文件打开表)分配一个文件描述符,并且指向对应的操作系统打开文件表即可。如果没有打开,那么就需要加载到内存中来。

EOF

EOF可以说是一个信号值,而在C语言编程里面,它其实就是-1。一般都说它是文件的末尾,会给人造成一种假象:文件最后是以这个符号作为特殊结尾的。其实不是这样的,每个文件的末尾并没有这么一个特殊的符号。

通过上面也知道,可以通过文件的inode知道它的大小,那么操作系统是完全可以知道文件是不是到达最后了,如果到达最后,那么就返回一个EOF信号。那标准输入怎么办呢?操作系统肯定是无法知道标准输入什么时候到了结尾的,这个时候就需要在键盘上输入ctrl+d,来人工发送这个信号。