用于读取目录的K&R接口:多余的DIR结构?

在Kernighan和Ritchie的“The C Programming Language”第二版中,他们实现了UNIX命令ls的简化版本(第8.6节“示例 – 列表目录” ,第179页)。 为此,他们创build了以下接口,它提供了一个独立于系统的对存储在目录中的文件的名称和inode号的访问。

 #define NAME_MAX 14 /* longest filename component; */ /* system dependent */ typedef struct { /* portable director-entry */ long ino; /* inode number */ char name[NAME_MAX+1]; /* name + '\0' terminator */ } Dirent; typedef struct { /* minimal DIR: no buffering, etc. */ int fd; /* file descriptor for directory */ Dirent d; /* the directory entry */ } DIR; DIR *opendir(char *dirname); Dirent *readdir(DIR *dfd); void closedir(DIR *dfd); 

然后他们为版本7和系统V UNIX系统实现这个接口。

现在我的问题是 :具有DIR结构的意义何在? 如果我对这个程序的理解是正确的, DIRDirent组件是不会被使用的,为什么不用一个文件描述符replace整个结构,直接使用open()close()呢?

谢谢。

Ps:我知道,在现代UNIX系统上, read()不能再用于目录(我已经在Ubuntu 10.04上试过这个程序),但是我仍然要确保在这个例子中我没有忽略一些重要的东西。

从K&R:

遗憾的是,目录的格式和精确内容在所有版本的系统上都不相同。 所以我们将这个任务分成两部分来试图隔离不可移植的部分。 外层定义了一个称为Dirent的结构,以及三个例程opendirreaddirclosedir,以提供对目录条目中名称和inode编号的系统无关的访问。

所以原因是便携性。 他们希望定义一个能够在具有不同统计结构或非标准open()close()系统上生存的接口。 他们继续围绕它构建一系列可重用的工具,甚至不关心它们是否在类Unix系统上。 这是包装的重点。

也许它没有被使用,因为他们通过定义他们的数据结构开始(DIR中有一个Dirent),但最终没有使用它。 保持这样的数据结构是很好的设计。

这样他们就不必为readdir返回的Dirent结构分配内存。 这样,他们可以在分包调用readdir之间重用Dirent。