文件的基本概念
文本文件和二进制文件
- 文件可分为文本文件(Text File)和二进制文件(Binary File)两种,源文件是文本文件,而目标文件、可执行文件和库文件是二进制文件。
- 文本文件是用来保存字符的,文件中的字节都是字符的某种编码(例如ASCII或UTF-8),用cat命令可以查看其中的字符,用vi可以编辑其中的字符 文本文件是一个模糊的概念。有些时候说文本文件是指用vi可以编辑出来的文件,例如/etc目录下的各种配置文件,这些文件中只包含ASCII码中的可见字符,而不包含像'\0'这种不可见字符,也不包含最高位是1的非ASCII码字节。从广义上来说,只要是专门保存字符的文件都算文本文件,包含不可见字符的也算,采用其它字符编码(例如UTF-8编码)的也算。
- 二进制文件不是用来保存字符的,文件中的字节表示其它含义,例如可执行文件中有些字节表示指令,有些字节表示各Section和Segment在文件中的位置,有些字节表示各Segment的加载地址。
vi编辑一个文件textfile,在其中输入5678然后保存退出,用ls -l命令可以看到它的长度是5:
$ ls -l textfile
-rw-r--r-- 1 akaedu akaedu 5 2009-03-20 10:58 textfile
5678四个字符各占一个字节,vi会自动在文件末尾加一个换行符,所以文件长度是5。用od命令查看该文件的内容:
$ od -tx1 -tc -Ax textfile
000000 35 36 37 38 0a
5 6 7 8 \n
000005
-tx1选项表示将文件中的字节以十六进制的形式列出来,每组一个字节 -tc选项表示将文件中的ASCII码以字符形式列出来。 -Ax选项要求以十六进制显示文件中的地址,输出结果最左边的一列是文件中的地址,默认以八进制显示 这样我们看到,这个文件中保存了5个字符,以ASCII码保存。ASCII码的范围是0~127,所以ASCII码文本文件中每个字节只用到低7位,最高位都是0。
$ hexdump -C textfile
00000000 35 36 37 38 0a |5678.|
00000005
文件系统结构
- 用户空间包含一些应用程序(例如,文件系统的使用者)和 GNU C 库(glibc),它们为文件系统调用(打开、读取、写和关闭)提供用户接口。
- 系统调用接口的作用就像是交换器,它将系统调用从用户空间发送到内核空间中的适当端点。
- VFS 是底层文件系统的主要接口,它是 Linux 内核中的一个软件抽象层。这个组件导出一组接口,然后将它们抽象到各个文件系统,各个文件系统的行为可能差异很大。有两个针对文件系统对象的缓存(inode 和 dentry)。它们缓存最近使用过的文件系统对象。
- 因为有 VFS 存在,Linux 允许众多不同的文件系统共存,并支持跨文件系统的文件操作。它通过一些数据结构及其方法向实际的文件系统如 ext2,vfat 提供接口机制。 每个文件系统实现(比如 ext2、JFS 等等)导出一组通用接口,供 VFS 使用。
- 缓冲区缓存会缓存文件系统和相关块设备之间的请求。例如,对底层设备驱动程序的读写请求会通过缓冲区缓存来传递。这就允许在其中缓存请求,减少访问物理设备的次数,加快访问速度。可以使用 sync 命令将缓冲区缓存中的请求发送到存储媒体(迫使所有未写的数据发送到设备驱动程序,进而发送到存储设备)。
cache和buffer
cache
在内存管理中,cache指的是:page cache。page cache即页面高速缓存,是针对文件系统的,存储的是文件的文件数据(文件分为元数据和文件数据)。
buffer
在内存管理中,buffer指的是:buffer cache。buffer cache是是块设备的读写缓冲区。操作系统是以块的概念操作磁盘的,一个块会包含一个或者多个扇区,但是不会超过一个页面大小。 buffers主要用于缓存文件系统中的元数据信息(dentries、inodes),和另外一些不是文件数据的块,例如metadata和raw block I/O,因此还是需要单独用buffer cache来缓存。
两者之间的关系
在内核2.6以后,两者结构进行统一,都是page cache,page中含有一个个的buffer结构,所以我们的free命令中,也将两者进行统一。 两者是配合使用的,当我们对一个文件进行写操作时候,page cache的内容会被改变,而buffer cache则可以将page标记不同的缓冲区(buffer),并记录哪个块被修改,这样,脏数据回写时候,就不用回写整个page,而只要回写修改的块。
总结
在 Linux 中,文件 Cache 分为两层,一是 Page Cache,另一个 Buffer Cache,每一个 Page Cache 包含若干 Buffer Cache。 内存管理系统和 VFS 只与 Page Cache 交互,内存管理系统负责维护每项 Page Cache 的分配和回收,同时在使用 memory map 方式访问时负责建立映射;VFS 负责 Page Cache 与用户空间的数据交换。 具体文件系统则一般只与 Buffer Cache 交互,它们负责在外围存储设备和 Buffer Cache 之间交换数据。读缓存以Page Cache为单位,每次读取若干个Page Cache,回写磁盘以Buffer Cache为单位,每次回写若干个Buffer Cache。 Page Cache、Buffer Cache、文件以及磁盘之间的关系如下图所示。
Page 结构和 buffer_head 数据结构的关系如下图所示。Page指向一组Buffer的头指针,Buffer的头指针指向磁盘块。在这两个图中,假定了 Page 的大小是 4K,磁盘块的大小是 1K。