opendir 和 readdir 背后编码字符串?

opendir 和 readdir 背后编码字符串?

(如果您能够回答问题,则可以跳过详细信息到最后几行:))

我使用的是 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 如何编码名称,或者使用一些其他处理原始字节的系统调用,而不是在我背后编码内容?一般来说,我发现在什么级别的编码发生时非常令人困惑,我希望得到任何解释或更好的理解这一点的参考!谢谢!

答案1

opendir它们readdir本身就以字节为单位工作。他们不执行和重新编码。

某些文件系统驱动程序可能会对字节序列施加限制。例如,HFS+ 使用专有的 Unicode 标准化方案标准化文件名。但是,我希望返回的表单readdir在传递给 时能够正常工作opendir,就像 OP 中的那样Ubuntu 论坛主题jw013 提及,我怀疑 HFS+ 驱动程序中存在错误。这是不是唯一的程序HFS+ 上的 Hangul 会触发该错误。甚至 OSX似乎有麻烦统一码正常化。

相关内容