# 10.7 读取目录内容

应用程序可以用 readdir 系列函数来读取目录的内容。

```c
#include <sys/types.h>
#include <dirent.h>

DIR *opendir(const char *name);

// 返回：若成功，则为处理的指针；若出错，则为 NULL。
```

函数 opendir 以路径名为参数，返回指向**目录流**（directory stream）的指针。流是对条目有序列表的抽象，在这里是指目录项的列表。

```c
#include <dirent.h>

struct dirent *readdir(DIR *dirp);

// 返回：若成功，则为指向下一个目录项的指针；
//      若没有更多的目录项或出错，则为 NULL。
```

每次对 readdir 的调用返回的都是指向流 dirp 中下一个目录项的指针，或者，如果没有更多目录项则返回 NULL。每个目录项都是一个结构，其形式如下：

```c
struct dirent {
    ino_t d_ino;      /* inode number */
    char d_name[256]; /* Filename */
};
```

虽然有些 Linux 版本包含了其他的结构成员，但是只有这两个对所有系统来说都是标准的。成员 d\_name 是文件名，d\_ino 是文件位置。

如果出错，则 readdir 返回 NULL，并设置 errno。可惜的是，唯一能区分错误和流结束情况的方法是检査自调用 readdir 以来 errno 是否被修改过。

```c
#include <dirent.h>

int closedir(DIR *dirp);

// 返回：成功为 0；错误为 -1。
```

函数 closedir 关闭流并释放其所有的资源。图 10-11 展示了怎样用 readdir 来读取目录的内容。

{% tabs %}
{% tab title="code/io/readdir.c" %}

```c
#include "csapp.h"

int main(int argc, char **argv)
{
    DIR *streamp;
    struct dirent *dep;

    streamp = Opendir(argv[1]);

    errno = 0;
    while ((dep = readdir(streamp)) != NULL) {
        printf("Found file: %s\n", dep->d_name);
    }
    if (errno != 0)
        unix_error("readdir error");

    Closedir(streamp);
    exit(0);
}
```

{% endtab %}
{% endtabs %}

> 图 10-11 读取目录的内容


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://hansimov.gitbook.io/csapp/part3/ch10-system-level-io/10.7-reading-directory-contents.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
