我尝试计算文件夹中的文件,但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;
}
答案 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,".")==0
和strcmp(entry->d_name,"..")==0
用于排除子目录。