2013-03-27 61 views
6

在Linux下,我有兩個文件路徑A和B:確定兩個文件路徑是否指向Linux/C下的同一文件?

const char* A = ...; 
const char* B = ...; 

我現在要決定,我應該open(2)他們兩個......

int fda = open(A, ...); 
int fdb = open(B, ...); 

...我會得到兩個文件句柄打開文件系統中的同一個文件?

要確定這一點,我認爲stat(2)

struct stat 
{ 
    dev_t st_dev; 
    ino_t st_ino; 
    ... 
} 

類似的信息(僞代碼):

bool IsSameFile(const char* sA, const char* sB) 
{ 
    stat A = stat(sA); 
    stat B = stat(sB); 

    return A.st_dev == B.st_dev && A.st_ino == B.st_ino; 
} 

是否有A和B是相同的文件,但IsSameFile會返回任何情況下,假?

是否有任何情況下,A和B是不同的文件,但IsSameFile將返回true?

有沒有更好的方法來做我想做的事情?

+0

你可以有多個引用同一個文件的文件描述符,是的。 – teppic 2013-03-27 02:12:31

+0

@teppic:是的,你也可以有多個引用不同文件的文件描述符。我的問題是如何確定我所處的(或將要處於哪個)這兩個宇宙中的哪一個 – 2013-03-27 02:17:18

+0

如果你確實打開了文件描述符,那麼你可以直接在它們上使用'fstat' - 如果inode和設備號相等,這兩個路徑不可能引用不同的文件。 – teppic 2013-03-27 02:41:57

回答

4

因爲A.st_ino會返回inode號碼您的系統中的文件,您的程序將在所有情況下正常工作。由於inode編號是唯一的,因此您的程序將正確識別打開的兩個文件是否相同。

您還可以檢查A.st_mode的值以確定該文件是否爲符號鏈接

+2

如果它實際上是一個破損的符號鏈接,那麼只能通過'stat()'發現一個名稱是(破碎的)符號鏈接。如果它沒有被破壞,'stat()'報告鏈接末尾的文件或設備;如果名稱是符號鏈接,那麼'lstat()'報告(第一個)符號鏈接。 – 2013-03-27 02:11:09

0

這取決於你爲什麼要避免兩次打開同一個文件。您的解決方案通常是正確的,但是在某些情況下,如果文件具有相同的絕對路徑,而不是鏈接到同一個索引節點的文件應該被視爲相同。在這種情況下,您需要將路徑轉換爲絕對路徑並將它們進行比較...請參閱Getting absolute path of a file

您還需要決定是否將文件的符號鏈接考慮爲等效於該文件的文件或其他符號鏈接。對於inode等價,它決定是使用stat還是lstat。對於路徑等價性,它決定您是否可以使用realpath或者如果您需要獲取絕對路徑而不遵循以下符號鏈接。

+1

使用'stat()',代碼將忽略符號鏈接(除了可能已損壞的代碼)。你能否詳細說明'某些情況下,如果文件具有相同的絕對路徑,而不是如果它們是同一個索引節點的鏈接,那麼這些文件應該被認爲是相同的? – 2013-03-27 02:12:52

+0

@JonathanLeffler「使用stat(),代碼將忽略符號鏈接」 - 但不使用* lstat * - 這正是我所做的區別。詳細說明:某些備份方案要求爲每個路徑複製一次文件(尤其是如果要對不支持硬鏈接的fs進行復原),但保存相同路徑兩次沒有意義。它們可能是其他用例。但正如我所說,inode的等價性通常是**所需的。 – 2013-03-27 02:22:55

+0

@JonathanLeffler實際上它是不知道符號鏈接的'lstat',而'stat'對它們做了一個有效的'readlink'並且遵循它們。實際上,'lstat'的實現就是'stat'在符號鏈接之前的實現(egads,那時我正在編寫UNIX內核代碼)。 – 2013-03-27 02:27:48

相關問題