我没有使用unicode

时间:2014-01-07 19:06:54

标签: c dirent.h

我尝试计算文件夹中的文件,但readdir函数会跳过包含unicode字符的文件。 我正在使用dirent,在c。

int filecount(char* path)
{
    int file_Count=0;
    DIR* dirp;
    struct dirent * entry;
    dirp = opendir(path);
    while((entry=readdir(dirp)) !=NULL)
    {
        if(entry->d_type==DT_REG)
        {
            ++file_Count;
        }
    }
    closedir(dirp);
    return file_Count;
}

2 个答案:

答案 0 :(得分:4)

在Mac OS X 10.9.1 Mavericks上进行测试,我将您的代码改编为以下完整程序:

#include <dirent.h>
#include <stdio.h>

static
int filecount(char *path)
{
    int file_Count = 0;
    DIR *dirp;
    struct dirent *entry;
    dirp = opendir(path);
    while ((entry = readdir(dirp)) != NULL)
    {
        printf("Found (%llu)(%d): %s\n", entry->d_ino, entry->d_type, entry->d_name);
        if (entry->d_type == DT_REG)
        {
            ++file_Count;
        }
    }
    closedir(dirp);
    return file_Count;
}

static void proc_dir(char *dir)
{
    printf("Processing %s:\n", dir);
    printf("File count = %d\n", filecount(dir));
}

int main(int argc, char **argv)
{
    if (argc > 1)
    {
        for (int i = 1; i < argc; i++)
            proc_dir(argv[i]);
    }
    else
        proc_dir(".");
    return 0;
}

值得注意的是,它会在返回时列出每个条目 - inode,type和name。在Mac OS X上,我被告知inode类型为__uint64_t又名unsigned long long,因此使用%llu作为格式; YMMV就是这样。

我还创建了一个文件夹utf8并在文件夹中创建了文件:

total 32
-rw-r--r--  1 jleffler  eng  6 Jan  7 12:14 ÿ-y-umlaut
-rw-r--r--  1 jleffler  eng  6 Jan  7 12:15 £
-rw-r--r--  1 jleffler  eng  6 Jan  7 12:14 €
-rw-r--r--  1 jleffler  eng  6 Jan  7 12:15 ™

每个文件都包含Hello和换行符。当我运行命令(我称之为fc)时,它给出了:

$ ./fc utf8
Processing utf8:
Found (8138036)(4): .
Found (377579)(4): ..
Found (8138046)(8): ÿ-y-umlaut
Found (8138067)(8): £
Found (8138054)(8): €
Found (8138078)(8): ™
File count = 4
$

欧元符号€是U + 20AC EURO SIGN,超出了普通单字节代码集的范围。英镑符号£是U + 00A3 POUND SIGN,因此它在拉丁文1字母(ISO 8859-1,8859-15)的范围内。商标符号™是U + 2122商标符号,也不在普通的单字节代码集范围内。

这表明,至少在某些平台上,readdir()与使用不属于Latin1字符集的Unicode字符的UTF-8编码文件名完美匹配。它还演示了我如何调试问题 - 和/或说明了我希望你运行的内容(上面的程序)以及你应该运行它的目录类型,以使你的案例成为readdir()在您的平台上不喜欢Unicode文件名。

答案 1 :(得分:2)

尝试更改

if(entry->d_type==DT_REG)

if((entry->d_type==DT_REG || entry->d_type==DT_UNKNOWN) 
    && strcmp(entry->d_name,".")==0 && strcmp(entry->d_name,"..")==0)

应该可以通过进一步计算未知类型的文件来计算这些文件。

请注意,strcmp(entry->d_name,".")==0strcmp(entry->d_name,"..")==0用于排除子目录。