每一個文件,都可以通過一個struct stat的結構體來獲得文件信息,其中一個成員st_nlink代表文件的鏈接數。
當通過shell的touch命令或者在程序中open一個帶有O_CREAT的不存在的文件時,文件的鏈接數為1。
通常open一個已存在的文件不會影響文件的鏈接數。open的作用只是使調用進程與文件之間建立一種訪問關系,即open之后返回fd,調用進程可以通過fd來read 、write 、 ftruncate等等一系列對文件的操作。
close()就是消除這種調用進程與文件之間的訪問關系。自然,不會影響文件的鏈接數。在調用close時,內核會檢查打開該文件的進程數,如果此數為0,進一步檢查文件的鏈接數,如果這個數也為0,那么就刪除文件內容。
link函數創建一個新目錄項,並且增加一個鏈接數。
unlink函數刪除目錄項,並且減少一個鏈接數。如果鏈接數達到0並且沒有任何進程打開該文件,該文件內容才被真正刪除。如果在unlilnk之前沒有close,那么依舊可以訪問文件內容。
綜上所訴,真正影響鏈接數的操作是link、unlink以及open的創建。
刪除文件內容的真正含義是文件的鏈接數為0,而這個操作的本質完成者是unlink。close能夠實施刪除文件內容的操作,必定是因為在close之前有一個unlink操作。
舉個例子簡單說明:通過shell touch test.txt
1、stat("test.txt",&buf);
printf("1.link=%d\n",buf.st_nlink);//未打開文件之前測試鏈接數
2、fd=open("test.txt",O_RDONLY);//打開已存在文件test.txt
stat("test.txt",&buf);
printf("2.link=%d\n",buf.st_nlink);//測試鏈接數
3、close(fd);//關閉文件test.txt
stat("test.txt",&buf);
printf("3.link=%d\n",buf.st_nlink);//測試鏈接數
4、link("test.txt","test2.txt");//創建硬鏈接test2.txt
stat("test.txt",&buf);
printf("4.link=%d\n",buf.st_nlink);//測試鏈接數
5、unlink("test2.txt");//刪除test2.txt
stat("test.txt",&buf);
printf("5.link=%d\n",buf.st_nlink);//測試鏈接數
6、重復步驟2 //重新打開test.txt
7、unlink("test.txt");//刪除test.txt
fstat(fd,&buf);
printf("7.link=%d\n",buf.st_nlink);//測試鏈接數
8、close(fd);//此步驟可以不顯示寫出,因為進程結束時,打開的文件自動被關閉。
順次執行以上8個步驟,結果如下:
1.link=1
2.link=1 //open不影響鏈接數
3.link=1 //close不影響鏈接數
4.link=2 //link之后鏈接數加1
5.link=1 //unlink后鏈接數減1
2.link=1 //重新打開 鏈接數不變
7.link=0 //unlink之后再減1,此處我們改用fstat函數而非stat,因為unlilnk已經刪除文件名,所以不可以通過 文件名訪問,但是fd仍然是打開着的,文件內容還沒有被真正刪除,依舊可以使用fd獲得文件信息。
執行步驟8,文件內容被刪除。。。。
摘自:
看了unlink()函數是對文件的刪除,於是寫了一個函數進行測試之,結果發現在調用了unlink以后仍然可以對文件進行讀寫操作,又看了一下書才明 白是我沒有明白unlink函數的真正含義:刪除目錄相並減少一個連接數,如果鏈接數為0並且沒有任何進程打開該文件,該文件內容才能被真正刪除,但是若 又進程打開了該文件,則文件暫時不刪除直到所有打開該文件的進程都結束時文件才能被刪除。