opendir 和 readdir 在我背后编码字符串?

bhh*_*988 6 character-encoding directory-structure

(如果你能回答这个问题,你可以跳过最后几行的细节:))

我在 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! ");
}   
Run Code Online (Sandbox Code Playgroud)

这是我为此获得的输出示例:

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 查看目录条目似乎没有问题。inode 编号在那里,它们被正确标记为目录(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!!!
Run Code Online (Sandbox Code Playgroud)

它无法打开目录。这让我很困惑,因为如果 opendir 只是报告目录条目中文件名的原始位,而 readdir 只是获取我给定的文件名并将其与正确的目录条目匹配,那么我会认为应该没有问题找到inode并打开目录。这似乎表明 opendir 对文件名并不完全诚实。

opendir 报告的目录条目中的文件名是否不是磁盘上的实际名称(即它们是否被编码)?如果是这样,我有什么方法可以控制 opendir 和 readdir 编码名称的方式,或者使用其他一些处理原始字节的系统调用,而不是在我背后编码东西?总的来说,我发现编码发生在什么级别上非常令人困惑,我希望得到任何解释或更好的解释,以了解这一点!谢谢!

Gil*_*il' 1

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

某些文件系统驱动程序可能会对字节序列施加限制。例如,HFS+ 使用专有的 Unicode 标准化方案标准化文件名。我希望返回的表单在readdir传递到 时能够正常工作,但是,就像jw013提到Ubuntu 论坛线程opendir中的 OP 一样,我怀疑 HFS+ 驱动程序中存在错误。它并不是唯一一个在 HFS+ 上被 Hangul 绊倒的程序。甚至 OSX似乎在Unicode规范化方面也遇到了麻烦。