文件的概念
文件的组成
Linux中文件一般由三部分组成:
1 | 文件名(dentry) | 文件名保存在dentry(目录)中 |
2 | 元数据(metadata) | 所有与文件相关的额外信息,保存在inode中 |
3 | 数据(data) | 文件的内容 |
文件名,并不是存在于文件里,他保存在目录项里。他就像我们每个人的名字,不是让自己知道的,是让别人记住的,这样他就能通过名字找到你,文件也一样。
元数据,保存着文件的大小,类型,权限,inode等,它类似于身份证,一眼就能让人看到你是男是女,哪的人,多少岁,身高三围......
数据,数据自然就是文件的内容咯
总的来说,每个文件都有以下这三层结构:dentry、inode和data。dentry含有文件名并关联inode,inode含有文件元数据并指向数据区(data)。
inode
理解inode,要先了解文件储存:
文件储存在硬盘上,硬盘的最小存储单位叫做"扇区"(Sector)。每个扇区储存512字节(相当于0.5KB)。操作系统读取硬盘的时候,不会一个个扇区地读取,这样效率太低,而是一次性连续读取多个扇区,即一次性读取一个"块"(block)。这种由多个扇区组成的"块",是文件存取的最小单位。"块"的大小,最常见的是4KB,即连续八个 sector组成一个 block。文件数据都储存在"块"中,那么很显然,我们还必须找到一个地方储存文件的元信息,比如文件的创建者、文件的创建日期、文件的大小等等。这种储存文件元信息的区域就叫做inode,中文译名为"索引节点"。每一个文件对应一个inode,硬盘上有多少文件,就有多少个inode。
inode的内容
1.字节数
2.属主信息
3.属组信息
4.读写执行权限
5.时间戳
5.1.ctime(inode上一次变动的时间)
5.2.mtime(文件上一次变动的时间)
5.3.atime(文件上一次打开的时间)
6.链接数
7.文件占据(块)block的位置
inode的大小
inode也会消耗硬盘空间,所以硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区(inode table),存放inode所包含的信息。
每个inode节点的大小,一般是128字节或256字节。inode节点的总数,在格式化时就给定,一般是每1KB或每2KB就设置一个inode。假定在一块1GB的硬盘中,每个inode节点的大小为128字节,每1KB就设置一个inode,那么inode table的大小就会达到128MB,占整块硬盘的12.8%。由于每个文件都必须有一个inode,因此有可能发生inode已经用光,但是硬盘还未存满的情况。这时,就无法在硬盘上创建新文件。查看每个硬盘分区的inode总数和已经使用的数量,可以使用df -i命令。
inode的号码
前面我们说过,inode类似于身份证明,每个inode都有一个号码,操作系统用inode号码来识别不同的文件。Unix/Linux系统内部不使用文件名区分文件,而使用inode号码来识别文件。对于系统来说,文件名只是inode号码便于识别的别称或者绰号。表面上,用户是通过文件名打开文件。实际上,系统内部这个过程分成三步:
1.首先,系统找到这个文件名对应的inode号码;
2.通过inode号码,获取inode信息;
3.最后,根据inode信息,找到文件数据所在的block,读出数据。
使用ls -i命令或者stat,可以看到文件名对应的inode号码
inode的作用
1.有时,文件名包含特殊字符,无法正常删除,这时直接删除inode节点,就能起到删除文件的作用。
2.移动文件或重命名文件,只是改变文件名在目录里的位置,不影响inode号码。
3.打开一个文件以后,系统就以inode号码来识别这个文件,不再考虑文件名。因此,通常来说,系统无法从inode号码得知文件名。
这里拓展一下,rm删除的并不是inode,而是目录项里的文件名,所以我们是可以通过inode值来还原文件,而且即使删除inode值,也不是立马删除的,文件还是会在硬盘里面放着,只不过它现在没有了身份,新的文件存入后,就会覆盖掉这部分,这部分无名无姓的数据才会消失。(这就是冠希哥即使删除了硬盘里的视频,数据还是被还原的原因-)
1.系统定时清理没有文件名的inode和block。
2.磁盘检查会清理。
3.增加新文件时,会优先占用没有文件名的inode和block。
当我们误删除时,应该立即关机,避免文件数据被覆盖或清除,再用数据恢复工具进行恢复。
目录文件
Unix/Linux系统中,目录(directory)也是一种文件。打开目录,实际上就是打开目录文件。
目录文件的结构非常简单,就是一系列目录项(dirent)的列表。每个目录项,由两部分组成:
1.所包含文件的文件名,
2.以及该文件名对应的inode号码。
软硬链接
硬链接
一般情况下,文件名和inode号码是"一一对应"关系,每个inode号码对应一个文件名。但是,Unix/Linux系统允许,多个文件名指向同一个inode号码。
这意味着,可以用不同的文件名访问同样的内容;对文件内容进行修改,会影响到所有文件名;但是,删除一个文件名,不影响另一个文件名的访问。这种情况就被称为"硬链接"(hard link)。
ln命令可以创建硬链接
软链接
文件A和文件B的inode号码虽然不一样,但是文件A的内容是文件B的路径。读取文件A时,系统会自动将访问者导向文件B。因此,无论打开哪一个文件,最终读取的都是文件B。这时,文件A就称为文件B的"软链接"(soft link)或者"符号链接(symbolic link)。
这意味着,文件A依赖于文件B而存在,如果删除了文件B,打开文件A就会报错:"No such file or directory"。这是软链接与硬链接最大的不同:文件A指向文件B的文件名,而不是文件B的inode号码,文件B的inode"链接数"不会因此发生变化。
ln -s命令可以创建软链接。
通过以上我们可以看出,软连接是依靠与原文件的文件名,当原文件的文件名删除以后软连接就无法打开了,而硬链接则不一样,硬链接是直接调用inode的,没有中间商赚差价,所以我们可以通过硬链接来实现一些重要文件的备份。
设备节点
文件系统中存在的设备节点与普通文件、目录或符号链接包含数据的方式不同。它工作起来就像是一个通往内核设备驱动的管道。当向设备节点写入数据时,它将数据传递给适当的内核设备驱动。当用户需要从某个设备读取数据时,从相应的设备节点读取数据,就像是直接从设备节点读取数据一样。按照惯例,设备节点存放在一个名为/dev的专用目录下。
/dev目录下有成百上千个文件,上面的输出被截短了。注意输出中第一个字符,/dev目录下的大多数文件都不是普通文件或目录,而是字符设备节点(“c”)或块设备节点(“b”)。这两种类型的设备节点反映了Linux设备驱动的两方面:
1.字符设备
按字节流依次读写的设备,如:键盘,打印机,鼠标,声卡
2.块设备。
块设备的读写是一次读写一大块数据。块设备允许随机访问,即一块数据可以从设备任意位置以任意顺序读取。典型的块设备如:硬盘、软驱、光驱等。
磁盘文件与挂载
1.磁盘设备
Linux(和UNIX)系统允许通过/dev目录下的设备节点对磁盘进行直接或低级访问。尽管磁盘设备节点默认存在,但是普通用户通常无权直接访问它们。有趣的是,/dev/cdrom并不是一个设备节点,而是一个软链接。它当前指向/dev/hdc。大部分现代光驱都通过IDE或SCSI接口连接到系统,因此对于系统而言仅仅是另一个IDE或SCSI设备而已。某些应用程序(例如gnome-cd CD播放器)需要访问光驱,它们只需要通过/dev/cdrom就可以访问光驱,而不要关心系统实际光驱设备节点名。在大多数情况下,磁盘都被划分为分区使用。分区能够当作是独立的磁盘来使用。就像针对磁盘的设备节点一样,也有针对分区的设备节点。分区的设备节点仅仅是在磁盘设备节点名后面加分区号而已。例如,主IDE通道上的从盘的第三个磁盘分区的设备节点为/dev/hdb3。
2.文件系统
人们不希望将数据仅依字节流形式存放于磁盘。人们都希望给个文件名,然后将信息保存在文件里;将文件放进目录里管理,并控制对其访问的权限。所有这些结构化的信息管理由文件系统完成。文件系统将磁盘划分成规定大小的数据块进行管理。文件系统对块的管理就像这样:“这个块用于存放i-节点”,“这个块用于存放目录表项”,“这三块和那一块用于存放/etc/resolv.conf文件的数据”或“这第一块用于追踪其他块的使用”。文件系统提供所有这些必要的信息。在文件系统可以用来存储这些信息前,它必须要经过初始化。在Linux系统中,这通常叫做创建文件系统;在其他系统中,这可能被叫做格式化。Linux支持很多不同的文件系统。Linux默认的文件系统是ext2(红帽企业版Linux中是ext3),它同样支持其他许多系统的默认文件系统,例如DOS FAT文件系统、OS/2 HPFS文件系统。在Linux系统中,mkfs命令族用于创建文件系统。因为这些命令通常由管理员执行,所以它们不在/bin或/usr/bin目录下,普通用户也不能调用执行。它们位于供管理员使用的/sbin目录下
3.mount挂载
mount 命令用来挂载文件系统。其基本命令格式为:
mount -t type [-o options] device dir
device:指定要挂载的设备,比如磁盘、光驱等。
dir:指定把文件系统挂载到哪个目录。
type:指定挂载的文件系统类型,一般不用指定,mount 命令能够自行判断。
options:指定挂载参数,比如 ro 表示以只读方式挂载文件系统。
我们可以使用mount来查看已经挂载的文件系统
输出中的每行代表挂载的一个文件系统,其格式为:
fs_spec on fs_file type fs_vfstype (fs_mntopts)
fs_spec:挂载的块设备或远程文件系统
fs_file:文件系统的挂载点
fs_vfstype:文件系统的类型
fs_mntopts:与文件系统相关的更多选项,不同的文件系统其选项也不太一样
想要了解更多请转到