2015-12-22 142 views
2

我正在學習文件鏈接計數。只有鏈接計數達到0時,才能刪除文件的內容。在我的測試中,該進程在目錄「/ home/hel/myfile」中打開一個文件並睡眠10(s)。同時我使用「rm/home/hel/myfile」刪除它。然後我使用命令「ls」並顯示No這樣的文件。但事實上,該文件仍然存在,因爲fd尚未關閉。如果是這樣,「ls」不能顯示文件是否真的存在。我對「ls」感到困惑。或者我怎麼能判斷一個文件真的存在?鏈接計數和ls命令

#include <fcntl.h> 
#include <stdlib.h> 

int main(void) 
{ 
    int fd; 

    fd = open("/home/hel/myfile", O_RDWR); 
    if (fd < 0) { 
     exit(-1); 
    } 
    sleep(10); // sleep 10(s) 
    close(fd); 
    return 0; 
} 
+0

你對鏈接是什麼感到困惑,而不是關於「ls」。鏈接與文件句柄不同;這是一個單獨的參考信息被佔領的inode ... – tink

回答

2

文件名就像一個指向真實數據的標籤。真實數據存儲在an inode。一個inode通常只有一個文件名指向它,鏈接數爲1。但它可以有多個。

下面是一個視覺示例。當您創建一個普通文件時,它會將您的數據放入一個新的inode中,並將文件名指向它。

$ echo "foo" > some/file 

    "some/file" -> [data: "foo", links: 1] 

當你創建另一個文件時,會發生同樣的事情。

$ echo "bar" > another/file 

    "some/file"  -> [data: "foo", links: 1] 
    "another/file" -> [data: "bar", links: 1] 

但是,如果你犯了一個hard link,現在的inode有兩個環節。

$ ln some/file some/link 

    "some/file"  -> [data: "foo", links: 2] 
        ^
    "some/link" -----/  

    "another/file" -> [data: "bar", links: 1] 

事實上,正常的文件是硬鏈接。沒有什麼區別some/filesome/link除了文件名。兩者都不是「真正的」文件,它們都是鏈接。

如果鏈接被刪除,鏈接計數遞減。這就是爲什麼在某些語言中,您可以撥打unlink來刪除文件。

$ rm some/file 

    "some/link"  -> [data: "foo", links: 1] 

    "another/file" -> [data: "bar", links: 1] 

當它達到0時,inode可以被覆蓋。數據仍然存在,但沒有指向它。這就是爲什麼你有時可以恢復被刪除的文件。

$ rm some/link 

        [data: "foo", links: 0] 

    "another/file" -> [data: "bar", links: 1] 

怎麼樣的文件句柄?他們不會更改鏈接計數。相反,在Unix(而不是Windows)上,操作系統會跟蹤給定inode有多少打開的句柄。只要有一個打開的句柄,它就不會允許inode被覆蓋。

fd = open("another/file", O_RDWR); 

         [data: "foo", links: 0] 

        fd ---\ 
         \/ 
     "another/file" -> [data: "bar", links: 1] 

$ rm another/file 

         [data: "foo", links: 0] 

        fd -> [data: "bar", links: 0] 

close(fd); 

         [data: "foo", links: 0] 

         [data: "bar", links: 0] 

這可以讓你做一些事情,如創建一個臨時文件,打開一個句柄來讀寫它,並立即刪除它。然後該程序可以繼續讀取和寫入臨時磁盤存儲,但沒有人可以看到該文件。

+1

非常清楚,真的很有用。謝謝! – hel