跳转到内容

C 编程/POSIX 参考/dirent.h

来自维基教科书,开放的书籍,为开放的世界

dirent.hC POSIX 库 中用于 C 编程语言 的头文件,包含用于简化目录遍历的构造。该函数不是 C 标准的一部分,但被认为是“伪标准”,通常在平台之间可移植。

名称 注释
int closedir(DIR* dirp) 关闭由 dirp 引用的目录流。返回后,dirp 可能不再指向可访问的 DIR 类型对象。如果使用文件描述符来实现 DIR 类型,则该文件描述符将被关闭。成功完成时,closedir() 返回 0。否则,返回 -1 并且 errno 被设置为指示错误。

errno 错误:EBADF 表示 dirp 不引用打开的目录流,EINTR 表示该函数被信号中断。

DIR* opendir(const char* dirname) 打开一个与 dirname 指定的目录对应的目录流。目录流定位在第一个条目处。如果 DIR 类型是使用文件描述符实现的,应用程序将只能打开总共不超过 OPEN_MAX 个文件和目录。成功完成时,opendir() 返回一个指向 DIR 类型对象的指针。否则,返回空指针并且 errno 被设置为指示错误。

errno 错误:EACCES 表示对 dirname 的路径前缀的组件拒绝搜索权限,或者对 dirname 拒绝读取权限。ELOOP 表示在解析路径时遇到太多符号链接。ENAMETOOLONG 表示 dirname 参数的长度超过 PATH_MAX,或者路径名组件超过 NAME_MAX。ENOENT 表示 dirname 的一个组件不是现有目录的名称,或者 dirname 是一个空字符串。ENOTDIR 表示 dirname 的一个组件不是目录。EMFILE 表示调用进程中当前打开了 OPEN_MAX 个文件描述符。ENAMETOOLONG 表示符号链接的路径名解析产生了一个中间结果,其长度超过 PATH_MAX。ENFILE 表示系统中当前打开了太多文件。

struct dirent* readdir(DIR* dirp) 返回一个指向表示由参数 dirp 指定的目录流中当前位置处的目录条目的结构的指针,并将目录流定位在下一个条目处。到达目录流末尾时,它返回一个空指针。如果点或点点的条目存在,将为点返回一个条目,为点点返回一个条目;否则将不返回它们。遇到错误时,将返回空指针,并设置 errno 以指示错误。遇到目录末尾时,将返回空指针,并且 errno 不改变。

返回值指向的内存位置由库管理,并在后续对 readdir 的调用中可能会改变。它不应由用户释放

errno 错误:EOVERFLOW 表示要返回的结构中的某个值不能被正确表示。EBADF 表示 dirp 不引用打开的目录流。ENOENT 表示目录流的当前位置无效。

int readdir_r(DIR* dirp, struct dirent* entry, struct dirent** result) entry 初始化为表示 dirp 中当前位置处的目录条目,将指向该结构的指针存储在 result 引用的位置,并将目录流定位在下一个条目处。entry 指向的存储将足够大,可以容纳一个 dirent,其 char d_name 成员的数组至少包含 NAME_MAX 加一个元素。成功返回时,在 *result 中返回的指针将具有与参数 entry 相同的值。到达目录流末尾时,该指针将具有 NULL 值。

errno 错误:EBADF 表示 dirp 不引用打开的目录流。

void rewinddir(DIR* dirp) 将 dirp 引用的目录流的位置重置到目录的开头。它还使目录流引用对应目录的当前状态,就像调用 opendir() 一样。如果 dirp 不引用目录流,则效果未定义。
void seekdir(DIR* dirp, long int loc) 将 dirp 指定的目录流上下次 readdir() 操作的位置设置为 loc 指定的位置。loc 的值应该是从之前的 telldir() 调用返回的。新位置恢复到与执行 telldir() 时关联的目录流的位置。如果 loc 的值不是从之前的 telldir() 调用获得的,或者在 telldir() 调用和 seekdir() 调用之间发生了 rewinddir() 调用,则后续调用 readdir() 的结果是不确定的。
long int telldir(DIR* dirp) 获取与 dirp 指定的目录流关联的当前位置。如果目录流上的最近一次操作是 seekdir(),则从 telldir() 返回的目录位置与为 seekdir() 提供的 loc 参数相同。成功完成时,telldir() 返回指定目录流的当前位置。

成员常量

[编辑 | 编辑源代码]

stdio.h 头文件中定义的常量包括

名称 注释
NAME_MAX (或 FILENAME_MAX) char 数组 d_name 的最大长度。

成员类型

[编辑 | 编辑源代码]

dirent.h 头文件中定义的数据类型包括

  • DIR - 表示目录流的结构。它的结构没有被 POSIX 定义,通常对用户来说是不透明的。
  • struct dirent - 具有以下成员的结构
  • ino_t d_ino - 文件序列号
  • char d_name[] - 条目的名称(不会超过 NAME_MAX 的大小)
  • 此外,struct dirent 可能会包含以下成员,具体取决于平台
  • off_t d_off - 文件偏移量
  • unsigned short int d_reclen - dirent 记录的长度
  • unsigned short int d_namlen - 名称的长度
  • unsigned int d_type - 文件类型

标准化

[编辑 | 编辑源代码]

dirent.h 包含在大多数 PC 架构的 C/C++ 库中。

已知 dirent.h 包含在以下编译器中

  • Turbo C++ (DOS)
  • GCC (跨平台)
  • MinGW (GCC 的 Microsoft Windows 版本)
  • Borland C++ Builder (Microsoft Windows)

Microsoft Visual C++ **不** 包含 dirent.h

dirent.h 使用的简短示例如下

/**************************************************************
 * A simpler and shorter implementation of ls(1)
 * ls(1) is very similar to the DIR command on DOS and Windows.
 **************************************************************/
#include <stdio.h>
#include <dirent.h>

int listdir(const char *path) 
{
  struct dirent *entry;
  DIR *dp;

  dp = opendir(path);
  if (dp == NULL) 
  {
    perror("opendir");
    return -1;
  }

  while((entry = readdir(dp)))
    puts(entry->d_name);

  closedir(dp);
  return 0;
}

int main(int argc, char **argv) {
  int counter = 1;

  if (argc == 1)
	listdir(".");

  while (++counter <= argc) {
    printf("\nListing %s...\n", argv[counter-1]);
    listdir(argv[counter-1]);
  }

  return 0;
}

将源代码放在一个文件 (listdir.c) 中,并像这样编译 (在 Linux shell 中)

gcc listdir.c -o listdir

或者像这样

gcc listdir.c -o listdir.exe

在 Windows/DOS 环境中。

现在,要运行 (在 Linux shell 中) 键入

 ./listdir

或者键入

 listdir.exe

在 Windows/DOS shell 中。

参考文献

[编辑 | 编辑源代码]
华夏公益教科书