温馨提示×

linux readdir如何处理中文

小樊
35
2026-09-08 15:42:32
栏目: 智能运维

在 Linux 下使用 readdir(以及相关的 opendir / readdir / closedir)处理中文文件名时,核心点其实不是 readdir 本身,而是“编码”问题。下面分点说明。


一、readdir 本身能处理中文吗?

readdir 返回的是 struct dirent,其中:

char d_name[256];

它保存的是文件系统原始字节序列,并不关心编码。

只要你的文件系统支持 UTF-8(Linux 默认就是),中文文件名在底层就是 UTF-8 字节流,readdir 原样返回,不需要任何特殊处理


二、常见“中文乱码”的原因

出现乱码,通常不是 readdir 的问题,而是:

1. 终端 / locale 不是 UTF-8

例如:

  • 终端使用 GBK
  • LANG 不是 *.UTF-8

检查:

locale

应该是类似:

LANG=zh_CN.UTF-8

如果不是:

export LANG=zh_CN.UTF-8

2. 程序内部按“窄字符 + 本地编码”处理

如果你用:

  • printf("%s\n", d_name) ✅ 正常
  • 但用非 UTF-8 假设处理字符串 ❌ 出错

✅ 正确做法:把 d_name 当 UTF-8 处理


三、C 语言示例(正确处理中文)

#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 库:

方法 1:使用 mbstowcs(不推荐复杂场景)

setlocale(LC_ALL, "");
wchar_t wname[256];
mbstowcs(wname, entry->d_name, 256);

方法 2(推荐):直接用 UTF-8 字符串库

  • C:utf8proc
  • C++:std::string + UTF-8 处理
  • Python:天然支持 UTF-8

五、C++ 示例(推荐)

#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:

  • 文件名可能是 GBK
  • readdir 返回 GBK 字节
  • 终端是 UTF-8 → 乱码

✅ 解决:

  • convmv 转换文件名编码
convmv -f gbk -t utf8 --notest *

七、总结一句话

readdir 对中文“无感知”,它只返回字节;只要系统、终端、程序都按 UTF-8 处理,中文文件名就完全没问题。

如果你有具体场景(比如:C / C++ / Python / shell / 跨平台),可以告诉我,我可以给更针对性的示例。

0