【Linux篇】第十篇——基础IO(系统文件IO+文件描述符+重定向+文件系统+软硬链接)(三)

简介: 【Linux篇】第十篇——基础IO(系统文件IO+文件描述符+重定向+文件系统+软硬链接)

文件系统


我们知道文件可以分为磁盘文件和内存文件,内存文件前面已经说过,现在说说磁盘文件

初始inode


概念:inode是在Linux操作系统中的一种数据结构,其本质是结构体,它包含了与文件系统中各个文件相关的一些重要信息。在Linux中创建文件系统时,同时回创建大量的inode。

磁盘文件由两部分构成,分别是文件内容和文件属性。文件内容就是文件当中存储的数据,文件属性就是文件的一些基本信息,例如文件名,文件大小以及文件创建时间等信息都是文件属性,问问价属性又被称为元信息。

在命令行输入ls -l,即可显示当前目录下各文件的属性信息。

image.png

其中各列信息所对应的信息如下所示:

image.png

在LINUX操作系统中,文件的元信息和内容是分离存储的,其中保存元信息的结构称为inode,因为系统当中可能存在大量的文件,所以我们需要给每个文件的属性集起一个唯一的编号,即inode号。也就是说,inode是一个文件的属性集合,Linux中几乎每个文件都有一个inode,为了区分系统当中大量的inode,我们为每个inode设置了编号


在命令行输入ls -i即可显示各个文件的inode编号

image.png

无论是文件内容还是文件属性,都是存储在磁盘当中的。

磁盘的概念


磁盘是一种永久性存储介质,在计算机中,磁盘几乎是唯一的机械设备,与磁盘相对应的就是内存,内存是掉电易失存储介质,目前所有的普通文件都是在磁盘中存储的。

磁盘在冯诺依曼体系结构中既可以充当输入设备,又可以充当输出设备

image.png

磁盘的寻优方案

对磁盘进行读写操作时,一般有以下几个步骤:

1.确定读写信息在磁盘的哪个盘面

2.确定读写信息在磁盘的哪个柱面

3.确定读写信息在磁盘的哪个扇区

通过以上步骤,可以确定信息在磁盘中的读写位置。

磁盘的分区与格式化介绍


线性存储介质

理解文件系统,首先我们必须将磁盘想象成一个线性的存储介质,想想磁带,当磁带被卷起来时,其就像磁盘一样是圆形的,但当我们把磁带拉直后,其就是线性的。

磁盘分区

磁盘通常被称为块设备,一般以扇区为单位,一个扇区的大小通常为512字节。我们若以大小为512G的磁盘为例,该磁盘就可以被分为十亿多个扇区。

image.png

计算机为了更好的管理磁盘,于是对磁盘进行了分区。磁盘分区就是使用分区编辑器在磁盘上划分几个逻辑部分, 盘片一旦划分成数个分区,不同的目录与文件就可以存储进不同的分区,分区越多,就可以将文件性质分的越细,按照更为细节的性质,存储在不同的地方以管理文件,例如在Windows下磁盘一般被分为C盘和D盘两个区域。


在Linux操作系统下,我们也可以通过以下命令查看我们磁盘的分区信息。

image.png

磁盘格式化

当磁盘完成分区后,我们还需要对磁盘进行格式化。磁盘格式化就是对磁盘中的分区进行初始化的一种操作1,这种操作通常会导致现有的磁盘或分区中所有的文件被清除。

简单来说,磁盘格式化就是对分区后的各个区域写入对应的管理信息。

image.png

其中,写入的管理信息是什么是由文件系统决定的,不同的文件系统格式化时写入的管理信息是不同的,常见的文件系统有EXT2,EXT3,XFS等。

EXT2文件系统的存储方案

计算机为了更好的管理磁盘,会对磁盘进行分区。而对于每一个分区来说,分区的头部会包括一个启动块(Boot Block),对于该分区的其余区域,EXT2文件系统会根据分区的大小将其划分为一个个的块组(Block Group).

image.png

注意:启动块的大小是确定的,而快组的大小是油格式化确实的,并且不能更改。


其次,每个组块都有着相同的组成结构,每个组块都由超级快(Super Block),快组描述符表(Group Descriptor Table),块位图(Block Bitmap),inode位图(inode Bitmap),inode表(inode Table)以及数据表(Data Block)组成。

image.png

Super Block: 存放文件系统本身的结构信息。记录的信息主要有:Data Block和inode的总量、未使用的Data Block和inode的数量、一个Data Block和inode的大小、最近一次挂载的时间、最近一次写入数据的时间、最近一次检验磁盘的时间等其他文件系统的相关信息。Super Block的信息被破坏,可以说整个文件系统结构就被破坏了。

Group Descriptor Table: 块组描述符表,描述该分区当中块组的属性信息。

Block Bitmap: 块位图当中记录着Data Block中哪个数据块已经被占用,哪个数据块没有被占用。

inode Bitmap: inode位图当中记录着每个inode是否空闲可用。

inode Table: 存放文件属性,即每个文件的inode。

Data Blocks: 存放文件内容。

注意:

如何理解创建一个空文件?

  • 通过遍历inode位图的方式,找到一个空闲的inode
  • 在inode表中找到对应的inode,并将文件的属性信息填充进inode结构中
  • 将该文件的文件名和inode指针添加到目录文件的数据块中。

如何理解对文件写入信息?

  • 通过文件的inode编号找到对应的inode结构。
  • 通过inode结构找到存储该文件内容的数据块,并将数据写入数据块
  • 若不存在数据块或申请的数据块已被写满,则通过遍历块位图的方式找到一个空闲的块号,并在数据区当中找到对应的空闲块,再将数据写入数据块,最后还需要建立数据块和inode结构的对应关系。

如何理解删除一个文件?

  • 将该文件对应的inode在inode位图当中置为无效。
  • 将该文件申请过的数据块在块位图当中置为无效。

因为此操作并不会真正将文件对应的信息删除,而只是将其inode号和数据块号置为了无效,所以当我们删除文件后短时间内是可以恢复的。

为什么说是短时间内呢,因为该文件对应的inode号和数据块号已经被置为了无效,因此后续创建其他文件或是对其他文件进行写入操作申请inode号和数据块号时,可能会将该置为无效了的inode号和数据块号分配出去,此时删除文件的数据就会被覆盖,也就无法恢复文件了。

为什么拷贝文件的时候特别慢,而删除文件却特别块?

因为拷贝文件需要先创建文件,然后再对该文件进行写入操作,该过程需要先申请inode号并填入文件的属性信息,之后还需要再申请数据块号,最后才能进行文件内容的数据拷贝,而删除文件只需将对应文件的inode号和数据块号置为无效,无需真正的删除文件,所以拷贝慢,而删除文件时很快的。

如何理解目录?

  • 都说在Linux下一切皆文件,目录当然也可以被看作为文件.
  • 目录有自己的属性信息,目录的inode结构当中存储的就是目录的属性信息,比如目录的大小,目录的拥有者等。
  • 目录也有自己的内容,目录的数据块当中存储的就是该目录下的文件名以及对应文件的inode指针。

注意:每个文件的文件名并没有存储在自己的inode结构当中,而是存储在该文件所处目录文件的文件内容当中。因为计算机并不关注文件的文件名,计算机只关注文件的inode号,而文件名和文件的inode指针存储在其目录文件的文件内容当中后,目录通过文件名和文件的inode指针即可将文件名和文件内容及其属性连接起来。

软硬链接


软链接


概念:软链接通过名字引用另一个文件,具有独立的inode,是一个独立的文件。里面的数据块存储了源文件的路径信息。

通过以下命令创建了一个文件的软链接

ln -s myfile myfile_S

image.png

通过ls -i -l命令我们可以看到,软链接文件的inode号与源文件的inode号是不同的,并且软链接文件的大小要比源文件的大小小得多

image.png

软链接又叫做符号链接,软链接文件相对于源文件来说是一个独立的文件, 该文件有自己的inode号,但是该文件只包含源文件的路径名,所以软链接文件的大小要比源文件小得多。软链接就类似于Windows操作系统当中的快捷方式。

image.png

但是软链接只是源文件的一个标记,当删除了源文件后,链接文件不能独立存在,虽然仍保留文件名, 但缺不能执行或查看软链接的内容了

image.png

硬链接


概念:硬链接通过inode引用另外一个文件和指向的文件共享同一个inode,不是一个独立的文件。在linux中可以让多个文件名对应于同一个inode.

In myproc myproc _c

image.png

通过ls -i -l 命令我们可以看到,硬链接文件的inode号与源文件的inode号是相同的,并且硬链接文件的大小与源文件的大小也是相同的,特别注意,当创建了一个硬链接文件后,该硬链接文件和源文件的硬链接数变成了2

image.png

硬链接文件就是源文件的一个别名,一个文件有几个文件名,该文件的硬链接数就是几,这里inode号为655989的文件有两个,因此该文件的硬链接数为2。


与软链接不同的是,当硬链接的源文件被删除后,硬链接文件仍能正常执行,只是文件的链接数减少了一个,因为此时该文件的文件名少了一个。


总之,硬链接就是让多个不在或者同一个目录下的文件名,同时能够修改同一个文件,其中一个修改后,所有与其有硬链接的文件都一起修改了。

为什么刚创建的目录的硬链接数是2?

我们创建的一个普通文件,该普通文件的硬链接数是1,因为此时该文件只有一个文件名。那为什么我们创建一个目录后,该目录的硬链接数是2?

image.png

因为每个目录创建后,该目录下默认会有两个隐含文件.和..,它们分别代表当前目录和上级目录,因此这里创建的目录有两个名字,一个是dir另一个就是该目录下的.,所以刚创建的目录硬链接数是2。通过命令我们也可以看到dir和该目录下的.的inode号是一样的,也就是说明它们代表的实际上是一个文件。

image.png

软硬链接的区别


  • 软链接是一个独立的文件,有独立的inode,而硬链接没有独立的inode
  • 软链接相当于快捷方式,硬链接本质没有创建文件,只是建立了一个文件名和已有的inode的映射关系,并写入当前目录。


相关文章
|
22小时前
|
存储 缓存 算法
【linux】认识“文件”的本质,理解“文件系统”的设计逻辑,体会linux优雅的设计理念
【linux】认识“文件”的本质,理解“文件系统”的设计逻辑,体会linux优雅的设计理念
|
22小时前
|
Linux 数据处理 Perl
深入探索Linux的rename命令:文件重命名利器
**Linux的`rename`命令是批量重命名文件的利器,基于正则表达式或Perl,支持预览、交互式确认及多种操作模式。常用示例:用`s/ /_/g`替换空格为下划线,`s/$/.txt/`添加扩展名,`s/\..*//`删除扩展名。使用时注意备份、测试命令、权限和正则表达式知识。**
|
2天前
|
Linux 数据处理
探索Linux下的readlink命令:解析符号链接的利器
`readlink`命令在Linux中用于揭示符号链接的指向,显示它们所链接的实际文件或目录的路径。它可以显示简洁的绝对路径(-f),处理循环链接(-e),或不加换行符输出(-n)。例如,查看`link.txt`指向:`readlink link.txt`;获取绝对路径:`readlink -f link.txt`。使用时要注意链接是否存在、权限问题和可能的循环链接。
|
2天前
|
Linux 数据处理
探索Linux下的readelf命令:深入了解ELF文件
`readelf`是Linux下分析ELF文件的命令行工具,用于查看文件头、节区、符号表等信息。支持可执行文件、共享库等多种类型。常用选项有`-h`(文件头)、`-l`(程序头)、`-S`(节区)、`-s`(符号表)、`-r`(重定位)和`-d`(动态节区)。结合其他工具如`objdump`,能深入理解二进制文件,助力开发和调试。
|
3天前
|
Linux 数据处理 vr&ar
Linux下的ranlib命令:静态库文件的索引生成器
`ranlib`是Linux用于加速静态库(.a文件)链接的工具,它生成索引以优化查找目标文件。当链接器处理静态库时,索引能快速定位目标,提升效率。命令如`ranlib libexample.a`创建索引。注意,新工具链可能已自动包含此功能,使用前应确保库文件未含索引,避免重复生成。
|
4天前
|
算法 Linux Windows
Linux|如何查找和删除重复文件
Linux|如何查找和删除重复文件
9 1
|
4天前
|
存储 Java
杭州 java IO流详解(借鉴-侵-删)
杭州 java IO流详解(借鉴-侵-删)
8 0
|
5天前
|
Java 数据处理 开发者
Java IO流专家级教程:深入理解InputStream/OutputStream和Reader/Writer的内部机制
【6月更文挑战第26天】Java IO流涉及字节流(InputStream/OutputStream)和字符流(Reader/Writer),用于高效处理数据输入输出。InputStream/OutputStream处理二进制数据,常使用缓冲提升性能;Reader/Writer处理文本,关注字符编码转换。两者都有阻塞IO操作,但Java NIO支持非阻塞。示例代码展示了如何使用FileInputStream/FileOutputStream和FileReader/FileWriter读写文件。理解这些流的内部机制有助于优化代码性能。
|
5天前
|
存储 自然语言处理 Java
Java IO流完全手册:字节流和字符流的常见应用场景分析!
【6月更文挑战第26天】Java IO流涵盖字节流和字符流,字节流用于二进制文件读写及网络通信,如图片和音频处理;字符流适用于文本文件操作,支持多语言编码,确保文本正确性。在处理数据时,根据内容类型选择合适的流至关重要。
|
5天前
|
Java 开发者
Java IO流实战技巧:如何优化InputStream/OutputStream和Reader/Writer的使用?
【6月更文挑战第26天】Java IO流优化涉及缓冲、资源管理、字符编码和流式处理。使用Buffered流提高读写效率,如`BufferedInputStream`和`BufferedReader`。确保资源关闭使用try-with-resources,如`try (InputStream is = ...) {...}`。处理文本时指定编码,如`InputStreamReader(is, StandardCharsets.UTF_8)`防止乱码。流式处理大文件,分块读写避免内存溢出,以减少内存占用。这些技巧能提升程序性能和健壮性。

热门文章

最新文章