(如果您能够回答问题,则可以跳过详细信息到最后几行:))
我使用的是 Ubuntu 12.04。我正在尝试解决我过去发布过的一个老问题(如果您好奇:https://superuser.com/questions/339877/trouble-viewing-files-with-non-english-names-on-hard-disk/339895#339895)。 Linux、Mac、HFS+ 和韩文命名的文件之间存在一个已知的兼容性问题,我今天花了一整天的时间试图最终找到某种解决方法。
基本上,我已经将 HFS+ 驱动器安装到了 Linux 上。正常的 ls 和 cd 无法访问这些文件,因为它们是韩语的。所以我写了一个C程序来尝试在最低级别访问这些文件,这样我就可以更确定在我背后不会发生任何事情:
DIR* dp;
struct dirent *ep;
char* parent = "/media/external/Movies";
dp = opendir( parent );
if( dp != NULL )
{
while( ep = readdir(dp) )
{
printf( "%d %s %X\t", ep->d_ino, ep->d_name, ep->d_type );
// now print out the filenames in hex
for( int i = 0; i != strlen( ep->d_name ) ; i++)
{
printf( "0x%X " , ep->d_name[i] & 0xff );
}
printf("\n");
}
closedir(dp);
}
else
{
perror("Couldn't open the directory! ");
}
这是我为此获得的输出示例:
433949 밀양 4 0xEB 0xB0 0x80 0xEC 0x96 0x91
413680 박쥐 4 0xEB 0xB0 0x95 0xEC 0xA5 0x90
434033 韩国 4 0xEB 0xB0 0x95 0xED 0x95 0x98 0xEC 0x82 0xAC 0xED 0x83 0x95
所以从表面上看,openddir 查看目录条目没有问题。索引节点号在那里,它们被正确标记为目录(4 表示目录),并且文件名似乎以 UTF-8 编码存储,因为这些十六进制是韩国文件名的正确 UTF-8 代码。但现在,如果我要对这些目录之一执行 readdir (并且我将使用十六进制文件名,以格外小心,以免在我背后发生任何事情):
unsigned char new_dirname[] = {'/',0xEB,0xB0,0x80,0xEC,0x96,0x91,'\0'};
unsigned char final[ strlen(parent) + strlen(new_dirname) + 1 ];
memcpy(final, parent, strlen( parent ));
strcpy(final + strlen(parent), dirname );
dp = opendir( final ); // dp == NULL here!!!
它无法打开该目录。这让我感到困惑,因为如果 opendir 只是报告目录条目中文件名的原始位,而 readdir 只是获取我给定的文件名并将其与正确的目录条目相匹配,那么我会认为应该没有问题找到索引节点并打开目录。这似乎表明 opendir 对文件名并不完全诚实。
opendir 报告的目录条目中的文件名不是磁盘上实际的文件名(即它们是否被编码)?如果是这样,有什么方法可以控制 opendir 和 readdir 如何编码名称,或者使用一些其他处理原始字节的系统调用,而不是在我背后编码内容?一般来说,我发现在什么级别的编码发生时非常令人困惑,我希望得到任何解释或更好的理解这一点的参考!谢谢!