在 Debian(Linux) 下,readdir 本身不会排序,它返回目录项的顺序是 文件系统决定的(通常是 hash 或 inode 顺序)。
如果你需要排序,必须在 用户态自己排序。
下面分几种常见情况说明。
readdir() / readdir64() 属于 POSIX 接口:
struct dirent *readdir(DIR *dirp);
✅ 不保证顺序
✅ 顺序依赖文件系统(ext4 / xfs / tmpfs 行为不同)
✅ 不能依赖它做排序
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int main() {
DIR *dir = opendir(".");
if (!dir) return 1;
struct dirent **namelist;
int n = scandir(".", &namelist, NULL, alphasort);
if (n < 0) return 1;
for (int i = 0; i < n; i++) {
printf("%s\n", namelist[i]->d_name);
free(namelist[i]);
}
free(namelist);
closedir(dir);
return 0;
}
✅ scandir() + alphasort()
✅ 最简单、最常用
✅ Debian / glibc 原生支持
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dirent.h>
int cmp(const void *a, const void *b) {
const char *na = *(const char **)a;
const char *nb = *(const char **)b;
return strcmp(na, nb);
}
int main() {
DIR *dir = opendir(".");
struct dirent *ent;
char *names[1024];
int count = 0;
while ((ent = readdir(dir))) {
names[count++] = strdup(ent->d_name);
}
qsort(names, count, sizeof(char *), cmp);
for (int i = 0; i < count; i++) {
printf("%s\n", names[i]);
free(names[i]);
}
closedir(dir);
return 0;
}
✅ 可自行扩展为:
. / ..readdir 只给文件名,需要 stat():
stat(ent->d_name, &st);
st.st_mtime // 修改时间
st.st_size // 文件大小
然后按这些字段 qsort
ls -1 | sort
ls -lt # 按时间
ls -lS # 按大小
⚠️ ls 默认 不保证顺序,但 -1 | sort 是稳定排序
| 场景 | 做法 |
|---|---|
| C 程序 | scandir + alphasort ✅ |
| 自定义排序 | readdir + qsort |
| 按时间/大小 | readdir + stat + qsort |
| Shell | `ls |
如果你愿意,可以告诉我:
. 和 ..?我可以直接给你完整可用代码。