温馨提示×

linux readdir如何分页

小樊
48
2026-10-05 14:42:17
栏目: 智能运维

在 Linux 下使用 readdir(或 readdir_r、getdents 等)读取目录时,目录本身并没有“分页”概念,通常是一次性遍历全部条目。如果你的目标是“像分页一样分批读取目录内容”,常见做法有下面几种。


一、最常用:在用户态自己做“分页”

readdir 本身就是一个迭代器:

DIR *dir = opendir(path);
struct dirent *entry;

while ((entry = readdir(dir)) != NULL) {
    // 每读一条,计数
}
closedir(dir);

分页思路

  • 维护一个 offset(偏移量)
  • 跳过前 page * size 条
  • 读取 size 条后停止

示例(伪代码)

int offset = page * size;
int count = 0;

while ((entry = readdir(dir)) != NULL) {
    if (count < offset) {
        count++;
        continue;
    }
    if (count >= offset + size)
        break;

    printf("%s\n", entry->d_name);
    count++;
}

✅ 优点:简单、可移植
❌ 缺点:每次都要从头遍历(大目录慢)


二、保存目录状态(避免重复遍历)

如果你需要多次分页请求(如 Web API):

方案 1:缓存目录列表

// 第一次读取全部
readdir → 存到数组/vector
// 后续直接切片
list[page*size : page*size+size]

✅ 适合目录不大
❌ 目录变化会不一致


方案 2:使用 telldir / seekdir(推荐)

DIR *dir = opendir(path);
off_t pos = telldir(dir);  // 记录位置

分页示例:

seekdir(dir, saved_pos);
for (int i = 0; i < size; i++) {
    entry = readdir(dir);
    if (!entry) break;
    printf("%s\n", entry->d_name);
}
saved_pos = telldir(dir);

✅ 不需要重新遍历
⚠️ 注意:

  • telldir/seekdir 不是 POSIX 强制高效
  • 某些文件系统(NFS)可能不可靠

三、底层方案:getdents / getdents64

readdir 内部调用 getdents64

#include <sys/syscall.h>
#include <linux/dirent.h>
  • 一次读取多个目录项
  • 可以自己控制 buffer 大小
  • 更高效,但复杂

适合:

  • 超大目录
  • 高性能工具(如 ls、find)

四、排序 & 稳定分页(重要)

如果目录会变化:

  • 按 inode 或 d_name 排序
  • 否则分页会重复/漏项

五、总结对比

方法 是否推荐 说明
readdir + 计数 ✅ 简单通用
缓存列表 ✅ 小目录
telldir/seekdir ✅✅ 多次分页
getdents ⚠️ 高性能场景
系统级分页 ❌ 不存在

如果你能说明:

  • 用在 C / C++ / Shell / Python
  • 目录规模(几千 / 上百万)
  • 是否允许缓存

我可以给你更具体的代码示例。

0 踩