Linux怎样读取一个文件/数据是怎么恢复的?
First and Foremost 写在最前面
本文会持续更新,在学朱有鹏老师的Linux多进程多线程ing,是对Linux_os最浅显的理解
Linux读取文件流程
文件IO效率和标准IO
在Linux里面的叫做API,在C语言里的叫做就库函数
(1)文件IO就指的是我们当前在讲的open、close、write、read等API函数
构成的一套用来读写文件的体系,这套体系可以很好的完成文件读写,但是效率并不是最高的。
(2)应用层C语言库函数提供了一些用来做文件读写的函数列表,叫标准IO。
标准IO由一系列的C库函数构成(fopen、fclose、fwrite、fread),
这些标准IO函数其实是由文件IO封装而来的
(fopen内部其实调用的还是open,fwrite内部还是通过write来完成文件写入的)。
标准IO加了封装之后主要是为了在应用层添加一个缓冲机制buffer,
这样我们通过fwrite写入的内容不是直接进入内核中的buf,
而是先进入应用层标准IO库自己维护的buffer中,
然后标准IO库自己根据操作系统单次write的最佳count来选择好的时机来完成write到内核中的buf
(内核中的buf再根据硬盘的特性来选择好的实际去最终写入硬盘中)。
如图所示:
第一个buffer是应用层的,第二个buffer是内核中的。
讲完文件读取流程,让我们再来看看文件是怎样被存放再硬盘中的:
文件在硬盘中的存储
(1)文件平时都在存放在硬盘中的,硬盘中存储的文件以一种固定的形式存放的,我们叫静态文件。
(2)一块硬盘中可以分为两大区域:
一个是硬盘内容管理表项,另一个是真正存储内容的区域。
操作系统访问硬盘时是先去读取硬盘内容管理表,
从中找到我们要访问的那个文件的扇区级别的信息,
然后再用这个信息去查询真正存储内容的区域,最后得到我们要的文件。
(3)操作系统最初拿到的信息是文件名,最终得到的是文件内容。
第一步就是去查询硬盘内容管理表,这个管理表中以文件为单位记录了各个文件的各种信息,
每一个文件有一个信息列表(我们叫inode,i节点,其实质是一个结构体,
这个结构体有很多元素,每个元素记录了这个文件的一些信息,
其中就包括文件名、文件在硬盘上对应的扇区号、块号那些东西·····)
强调:硬盘管理的时候是以文件为单位的,每个文件一个inode,
每个inode有一个数字编号,对应一个结构体,结构体中记录了各种信息。
内存中被打开的文件和vnode(v节点)
(1)一个程序的运行就是一个进程,我们在程序中打开的文件就属于某个进程。
每个进程都有一个数据结构用来记录这个进程的所有信息(叫进程信息表),
表中有一个指针会指向一个文件管理表,
文件管理表中记录了当前进程打开的所有文件及其相关信息。
文件管理表中用来索引各个打开的文件的index就是文件描述符fd,
我们最终找到的就是一个已经被打开的文件的管理结构体vnode
(2)一个vnode中就记录了一个被打开的文件的各种信息,
而且我们只要知道这个文件的fd,
就可以很容易的找到这个文件的vnode进而对这个文件进行各种操作。
conclusion
- 创建一个进程,得到一个进程信息表
- 根据文件在硬盘中存储的位置得到文件的fd(file describe)
- 只要打开一个文件就会创建一个文件管理表vnode,记录了被打开文件的各种信息
- 得到以上三个信息就可以对文件进行读写操作了。
- 为了避免对硬件的多次访问,所以建立了缓存机制,每个缓存2M,通过lseek函数定位到自己想要修改的位置
- 两个进程共享同一个文件的实现:o_append属性。
数据恢复原理
联系平时实践,大家格式化硬盘(U盘)时发现有:快速格式化和底层格式化。
快速格式化非常快,格式化一个32GB的U盘只要1秒钟,普通格式化格式化速度慢。
这两个的差异?其实快速格式化就是只删除了U盘中的硬盘内容管理表(其实就是inode),
真正存储的内容没有动。这种格式化的内容是有可能被找回的。
底层格式化是很难找回的,需要通过flash的记忆找回,费用很高。
请大家批评指正
over