初识文件
文件的概念
在学习内存、进程的时候我们了解到了,程序运行需要将数据从外存移动到内存。在接下来的学习,我们将目标从内存转换到外存,看看数据在外存中是个什么组织方式吧。
文件是以硬盘为载体的存储在计算机中信息的集合。上面我们提到的数据,在外存中就成为文件。在Linux系统中就提出过这样一个概念:万物皆文件。文件的组织方式是什么?文件有什么作用?这些问题都会在下面一一解答。
文件的属性
当我们创建一个文件,并且编写这个文件。我们改变的是这个文件的数据项部分,还有一些其他部分是由操作系统为我们创建好的,称为文件属性。文件属性有以下几种:
名称:要求文件名称唯一,且要容易读取。
类型:被不同类型的文件系统使用。
创建者:文件创建者的ID;
所有者:当前所有者的ID;
位置:指向设备或设备上文件的指针;
大小:文件的当前大小;
保护:进行保护的访问控制信息;
创建时间:最后一次修改时间和最后一次存取时间。
这些文件属性我们可以很轻易地查看:例如在Windows系统中,右击文件单击属性就能查看文件的所有属性。

在Linux系统中,使用ls -l命令可以查看文件的基本属性,例如:
~# ls -l frp
total 17840
-rw-r--r-- 1 root root 142 Jun 4 10:11 frpc.toml
-rwxr-xr-x 1 root root 18239640 Jun 4 10:11 frps
-rw-r--r-- 1 root root 209 Jun 4 10:30 frps.ini
-rw-r--r-- 1 root root 16 Jun 4 10:11 frps.toml
-rw-r--r-- 1 root root 11358 Jun 4 10:11 LICENSE在这个命令的输出中,每一行代表一个文件或目录的信息:
文件权限(-rw-r--r--):第一个字符表示文件类型(
-表示普通文件,d表示目录)。接下来的九个字符分为三组,每组三个字符,分别表示所有者、组和其他用户的权限。
r表示可读(read)w表示可写(write)x表示可执行(execute)
链接数:文件的硬链接数量。
所有者:文件所有者的用户名。
组:文件所属组的组名。
文件大小:以字节为单位的文件大小。
修改日期和时间:文件最后修改的日期和时间。
文件名:文件的名称。
文件的分类
文件可以按照管理方式、用途等进行分类,下面是几种常见的分类方法:
按性质和用途分类:系统文件、用户文件、库文件。
按数据形式分类:源文件、目标文件、可执行文件。
按存取控制属性分类:可执行文件、只读文件、读写文件。
按组织形式和处理方式分类:普通文件、目录文件、特殊文件。
文件的逻辑结构
文件的数据部分可以根据组织形式来进行分类。如果无特定结构的文件,称作无结构文件。例如说我们常用的txt文件。还有一类文件有特定的组织结构,这类文件称作有结构文件。
有结构文件可分为以下三种:
顺序文件
顺序文件是最简单的文件结构,数据按照自然顺序逐条存储。
特点:
数据按写入顺序存储。
适合批处理操作。
插入和删除操作效率较低,因为需要移动大量数据。
优点:
简单易于实现。
对于顺序访问非常高效。
缺点:
随机访问效率低。
更新操作(插入/删除)可能需要重写整个文件。
索引文件
索引文件为数据文件建立一个索引,类似于书的目录,帮助快速定位数据。
特点:
包含索引区和数据区。
索引区存储关键字和指向数据的指针。
优点:
提供快速的随机访问。
适合频繁的查找操作。
缺点:
需要额外的存储空间来维护索引。
索引更新会增加插入和删除操作的复杂性。
索引顺序文件
索引顺序文件结合了顺序文件和索引文件的优点,通过索引实现快速访问,同时保持数据的顺序存储。
特点:
数据按顺序存储,并有一个或多个索引。
主索引用于快速查找记录,辅助索引用于二级查找。
适合既需要顺序访问又需要快速随机访问的场景。
优点:
顺序和随机访问性能较好。
插入和删除操作较为灵活。
缺点:
索引维护增加了复杂性。
需要更多的存储空间。
文件的操作
操作系统可以对文件进行以下操作:
创建文件:先为新文件分配额外内存空间、再在目录中创建一个目录项,目录项记录了文件名、文件在外存中的地址等信息。
读文件:根据文件名查找目录,找到对应目录项,得到在外存的地址。
删除文件:删除目录项,回收文件所占用的存储空间。
写文件:查找目录项找到对应地址,使用目录项的写指针对文件进行写操作,写操作结束后更新写指针。
在上面这些操作中,必然会涉及到文件的打开和关闭操作。操作系统具体打开文件的过程如下:
检索目录,使用系统调用open,系统将会维护一个打开文件信息的表,打开文件信息表中插入该文件的目录项。
将该表目的索引号(文件描述符)返回给用户。
如果用户多次请求打开相同文件,系统就可以高效的检索打开文件表,将对应的信息返回给用户。
操作系统关闭文件的过程如下:
系统的打开文件表中会维护一个打开计数器,记录多少进程打开了该文件。
文件不再使用,就会利用系统调用close关闭。此时打开计数器会递减。
当打开计数器为0时,则可以真正关闭这个文件,系统表中可以删除相应条目。
文件保护
为了安全起见,操作系统为用户提供的文件权限是有限的。例如,重要的系统内核文件,用户不应该能修改、删除。文件系统必须控制用户对文件的读取。常用的文件保护机制有口令保护、加密保护和访问控制等方式实现。口令保护、加密保护可以参见我的这篇文章:
这里着重介绍文件访问控制这方面。
访问类型有许多种:读、写、执行、添加、删除等。更细分还可以对文件的重命名、复制编辑进行控制。访问控制的方法就是根据用户身份进行控制。每个文件或目录有一个访问控制列表,可以规定每个用户及其允许的访问控制类型。此外还可以采用精简的访问控制列表,精简的控制列表将用户分为三种类型:
拥有者:创建文件的用户;
组:一组需要共享文件且具有类似访问的用户;
其他:系统内的其余用户。
Linux如何更改文件的权限?可以使用
chmod命令。以某一文件为例,使用ls -l 查看其属性,发现如下:-rw-r--r--表示所有者有读写权限,本组和其他用户只有读权限。利用chmod的数字模式更改这个文件的权限:
chmod 764 test.txt。表示这个文件本用户有读、写、执行权限,同组用户只有读写权限,其他用户只有读权限。不同数字代表的权限类型不同,基础类型如下:
r(读) = 4;w(写) = 2;x(执行) = 1。若要组合这些权限,简单的加和即可。
文件控制块FCB
和进程管理中的PCB类似,文件管理中也会使用FCB来存储文件的信息。文件与FCB一一对应,FCB的有序集合称为文件目录。一个FCB就是一个文件目录项,用来记录文件的各种属性。
FCB包含以下信息:
文件名:文件的名称及其路径。
文件大小:文件的字节数。
文件位置指针:当前读/写操作的位置。
文件所有者:文件的所有者信息。
权限信息:文件的访问权限(读、写、执行)。
时间戳:文件的创建时间、修改时间和访问时间。
文件类型:文件的类型(普通文件、目录、链接等)。
物理地址:文件在磁盘上的物理位置或指向磁盘块的指针。
链接计数:指向该文件的硬链接数量。
状态信息:文件的状态(打开、关闭、锁定等)。
评论区