linux

Linux readdir如何支持文件名编码转换

小樊
32
2025-06-01 23:16:12
栏目: 智能运维

在Linux中,readdir函数用于读取目录中的文件和子目录。默认情况下,readdir返回的文件名是按照当前系统的locale设置的编码格式。如果你需要处理不同编码的文件名,例如UTF-8编码的文件名,你需要进行编码转换。

以下是一个使用readdiriconv库进行文件名编码转换的示例:

#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <iconv.h>
#include <string.h>

char *convert_encoding(const char *input, const char *from_charset, const char *to_charset) {
    iconv_t cd = iconv_open(to_charset, from_charset);
    if (cd == (iconv_t)-1) {
        perror("iconv_open");
        return NULL;
    }

    size_t in_len = strlen(input);
    size_t out_len = in_len * 4; // 足够大的缓冲区
    char *output = malloc(out_len);
    if (!output) {
        perror("malloc");
        iconv_close(cd);
        return NULL;
    }

    char *in_buf = (char *)input;
    char *out_buf = output;

    if (iconv(cd, &in_buf, &in_len, &out_buf, &out_len) == (size_t)-1) {
        perror("iconv");
        free(output);
        iconv_close(cd);
        return NULL;
    }

    *out_buf = '\0'; // 添加字符串结束符
    iconv_close(cd);
    return output;
}

int main(int argc, char *argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <directory>\n", argv[0]);
        return 1;
    }

    const char *dir_path = argv[1];
    DIR *dir = opendir(dir_path);
    if (!dir) {
        perror("opendir");
        return 1;
    }

    struct dirent *entry;
    while ((entry = readdir(dir)) != NULL) {
        if (entry->d_name[0] == '.') continue; // 跳过当前目录和上级目录

        char *utf8_name = convert_encoding(entry->d_name, "GBK", "UTF-8");
        if (utf8_name) {
            printf("%s\n", utf8_name);
            free(utf8_name);
        } else {
            printf("Failed to convert filename: %s\n", entry->d_name);
        }
    }

    closedir(dir);
    return 0;
}

在这个示例中,我们使用iconv库将GBK编码的文件名转换为UTF-8编码。你需要根据实际情况修改from_charsetto_charset参数。

编译这个程序时,需要链接iconv库:

gcc -o readdir_encoding readdir_encoding.c -liconv

然后运行程序:

./readdir_encoding <directory>

<directory>替换为你想要读取的目录路径。程序将输出转换后的UTF-8编码的文件名。

0
看了该问题的人还看了