温馨提示×

linux readdir为何乱码

小樊
50
2026-09-29 19:53:03
栏目: 智能运维

在 Linux 下使用 readdir() 读取目录时出现“乱码”,通常不是 readdir() 本身的问题,而是编码不一致或显示方式不对导致的。下面按常见原因逐一说明。


一、最常见原因:文件名编码不是 UTF-8

1. 文件系统编码与终端编码不一致

Linux 文件系统本身不关心编码,文件名只是字节序列。

如果文件名是以 GBK / GB2312 / ISO-8859-1 等编码保存的,而你的:

  • 终端是 UTF-8
  • 程序直接打印字节

就会出现乱码。

✅ 表现:

printf("%s\n", dirent->d_name); // 乱码

✅ 解决思路:

  • 确认文件名真实编码
  • 使用 iconv 转换编码后再显示

示例(GBK → UTF-8):

iconv_t cd = iconv_open("UTF-8", "GBK");
iconv(cd, &in, &inlen, &out, &outlen);

二、Locale 没有正确设置

2. 程序运行环境不是 UTF-8 Locale

如果系统 locale 是:

LANG=C

那么:

  • 很多库会按字节处理
  • 中文字符容易显示异常

✅ 检查:

locale

✅ 推荐设置:

export LANG=zh_CN.UTF-8
export LC_ALL=zh_CN.UTF-8

三、终端本身不支持 UTF-8

3. 终端编码设置错误

即使程序和文件都是 UTF-8,如果:

  • PuTTY / Xshell / 老终端设置为 GBK
  • 或字体不支持中文

也会看起来像乱码。

✅ 检查终端设置:

  • 编码:UTF-8
  • 字体:支持中文(如 Noto / WenQuanYi)

四、readdir 返回的是字节,不是“字符串”

4. 你误把字节当字符串处理

dirent->d_name 是:

char d_name[256]; // 原始字节

如果你:

  • 用 wchar_t
  • 或做了错误的宽字符转换

也会乱码。

✅ 正确方式(UTF-8 环境):

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

五、挂载了 Windows / FAT / NTFS 分区

5. Windows 文件系统编码问题

NTFS / FAT 在 Linux 下挂载时:

  • 默认可能用 iocharset=iso8859-1
  • 中文会变成乱码

✅ 正确挂载方式:

mount -o iocharset=utf8 /dev/sdb1 /mnt

或 /etc/fstab:

/dev/sdb1 /mnt ntfs-3g defaults,iocharset=utf8 0 0

六、文件名本身已损坏(少见)

极少数情况:

  • 文件名本身就是非法 UTF-8
  • 或曾经被错误转换

✅ 可用:

convmv -f gbk -t utf8 -r --notest /path

快速排查清单 ✅

  1. locale 是否是 UTF-8?
  2. 终端编码是否是 UTF-8?
  3. 文件名是不是 GBK 编码?
  4. 是否挂载了 Windows 分区?
  5. 是否直接 printf("%s", d_name)?

如果你愿意,可以把:

  • 你的 readdir 示例代码
  • locale 输出
  • 乱码截图或字节(hexdump)

发出来,我可以精确判断是哪一种乱码。

0 踩