
(如果您能夠回答問題,則可以跳過詳細資訊到最後幾行:))
我使用的是 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 如何編碼名稱,或者使用一些其他處理原始位元組的系統調用,而不是在我背後編碼內容?一般來說,我發現在什麼級別的編碼發生時非常令人困惑,我希望得到任何解釋或更好的理解這一點的參考!謝謝!