文件系统技术内幕:大数据时代海量数据存储之道
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

2.3 如何遍历目录中的文件

文件系统有一个常用的功能就是查看某个目录的文件列表。这个功能对应的命令行工具就是ls命令。而在GUI管理工具中,其实就是展示在我们面前的目录和文件列表等内容。

从本质上来说,目录与文件并没有太大的差异。我们也可以将目录理解为一个文件,其中的数据是一些此目录下的所有文件名相关的内容。关于目录内容的相关原理,会在后续章节进行详细介绍,本节不再赘述。

本节从程序员开发的角度介绍一下如何查看目录的内容,也就是遍历目录中的文件。Linux有一个专门的API来实现目录的遍历,这个API就是readdir。下面实现一个类似ls的命令,但是功能上要比ls命令弱很多,如代码2-2所示。

代码2-2 遍历目录的实现

这个程序的实现很简单,只是输出当前目录下的所有文件和子目录。编译上述代码后运行,可以得到如下结果。对比readdir命令的结果和ls命令的结果,可以看出没有太大的差异。差异在于我们实现的命令输出了当前目录(.)和父目录(..)。

图2-4 输出结果

通过阅读上述代码我们可以知道,这里目录项的内容是以结构体dirent(directory entry的缩写)存储的。我们可以看一下该结构体的定义(来自glibc2.32),如代码2-3所示。

代码2-3 目录项数据结构

通过观察该数据结构就会发现,这个数据结构只有inode ID和文件名称等信息与ls命令展示的相关。那么ls命令显示的文件的详细信息(如文件的创建时间、大小和权限等)又是如何获取的呢?

要想回答这个问题,就要看一下系统提供的一个API函数。这个API函数就是stat()函数,该函数的语法格式如下:

从stat()函数的语法格式可以看出,该函数最主要的功能是返回一个stat类型的结构体。该结构体的定义如代码2-4所示(来自glibc 2.32)。从该结构体的定义我们可以看出,这里面包含文件非常详细的信息。通过这些信息,我们完全可以实现一个完整版的ls命令。

代码2-4 文件属性数据结构

关于如何实现一个完整版的ls命令本书不再赘述,大家可以自己思考并试着实现。如果实在不知道怎么写,则可以参考ls命令的源代码实现。