在 Linux 下使用 readdir(以及相关的 opendir / readdir / closedir)处理中文文件名时,核心点其实不是 readdir 本身,而是“编码”问题。下面分点说明。
✅ 能。
readdir 返回的是 struct dirent,其中:
char d_name[256];
它保存的是文件系统原始字节序列,并不关心编码。
只要你的文件系统支持 UTF-8(Linux 默认就是),中文文件名在底层就是 UTF-8 字节流,readdir 原样返回,不需要任何特殊处理。
出现乱码,通常不是 readdir 的问题,而是:
例如:
LANG 不是 *.UTF-8检查:
locale
应该是类似:
LANG=zh_CN.UTF-8
如果不是:
export LANG=zh_CN.UTF-8
如果你用:
printf("%s\n", d_name) ✅ 正常✅ 正确做法:把 d_name 当 UTF-8 处理
#include <stdio.h>
#include <dirent.h>
int main() {
DIR *dir = opendir(".");
struct dirent *entry;
while ((entry = readdir(dir)) != NULL) {
printf("%s\n", entry->d_name);
}
closedir(dir);
return 0;
}
✅ 在 UTF-8 环境下,中文文件名会正常显示
strlen / strcpy 当“字符数”因为 UTF-8 中一个汉字占 3 字节。
✅ 用宽字符或 UTF-8 库:
mbstowcs(不推荐复杂场景)setlocale(LC_ALL, "");
wchar_t wname[256];
mbstowcs(wname, entry->d_name, 256);
#include <dirent.h>
#include <iostream>
int main() {
DIR* dir = opendir(".");
dirent* ent;
while ((ent = readdir(dir))) {
std::cout << ent->d_name << std::endl;
}
closedir(dir);
}
如果你从 Windows(GBK) 拷贝文件到 Linux:
readdir 返回 GBK 字节✅ 解决:
convmv 转换文件名编码convmv -f gbk -t utf8 --notest *
readdir 对中文“无感知”,它只返回字节;只要系统、终端、程序都按 UTF-8 处理,中文文件名就完全没问题。
如果你有具体场景(比如:C / C++ / Python / shell / 跨平台),可以告诉我,我可以给更针对性的示例。