Linux下開發-揭祕檔案連結數
struct stat
每一個檔案,都可以通過一個struct stat的結構體來獲得檔案資訊,其中一個成員st_nlink代表檔案的連結數。
struct stat {
dev_t st_dev; /* ID of device containing file */
ino_t st_ino; /* inode number */
mode_t st_mode; /* protection */
nlink_t st_nlink; /* number of hard links */
uid_t st_uid; /* user ID of owner */
gid_t st_gid; /* group ID of owner */
dev_t st_rdev; /* device ID (if special file) */
off_t st_size; /* total size, in bytes */
blksize_t st_blksize; /* blocksize for file system I/O */
blkcnt_t st_blocks; /* number of 512B blocks allocated */
time_t st_atime; /* time of last access */
time_t st_mtime; /* time of last modification */
time_t st_ctime; /* time of last status change */
};
open
當通過shell的touch命令或者在程式中open一個帶有O_CREAT的不存在的檔案時,檔案的連結數為1。
通常open一個已存在的檔案不會影響檔案的連結數。open的作用只是使呼叫程式與檔案之間建立一種訪問關係,即open之後返回fd,呼叫程式可以通過fd來read、write 、 ftruncate等等一系列對檔案的操作。
close
close()就是消除這種呼叫程式與檔案之間的訪問關係。自然,不會影響檔案的連結數。在呼叫close時,核心會檢查開啟該檔案的程式數,如果此數為0,進一步檢查檔案的連結數,如果這個數也為0,那麼就刪除檔案內容。
link
link函式建立一個新目錄項,並且增加一個連結數。
unlink
int unlink( constchar* pathname);
此函式刪除目錄項,並將由pathname所引用檔案的連結計數減1。如果還有指向該檔案的其它連結,則仍可通過其他連結訪問該檔案的資料。如果出錯,則不對該檔案做任何更改。
只有當連結計數達到0時,該檔案的內容才可被刪除。
關閉一個檔案時,核心首先檢查開啟該檔案的程式數。如果該數達到0,然後核心檢查其連結數,如果這個數也是0,那麼就刪除該檔案的內容。
int main(void) {
int fd;
char buf[20] = {0};
if ((fd =open("tempfile", O_RDWR)) < 0)
err_sys("open error");
if (unlink("tempfile") < 0)
err_sys("unlink error");
printf("file unlinked/n");
read(fd, buf, sizeof(buf));//you could still read this after unlink
printf("%s/n", buf);
}
unlink的這種性質經常被用來確保即使是在該程式崩潰時,它所建立的臨時檔案也不會遺留下來。程式用open或create建立一個檔案,然後立即呼叫unlink。因為該檔案仍舊是開啟的,所以不會將其內容刪除。只有當程式關閉該檔案或終止時(在這種情況下,核心會關閉該程式開啟的全部檔案),該檔案的內容才會被刪除。
如果pahtname是符號連結,那麼unlink刪除該符號連結,而不會刪除由該連結所引用的檔案。
remove
int remove(constchar* pathname);
我們也可以用remove函式解除對一個檔案或目錄的連結。對於檔案,remove的功能與unlink相同。
ISO C指定remove函式刪除一個檔案,這更改了UNIX系統歷來使用的名字unlink,其原因是實現C標準的大多數非UNIX系統並不支援檔案連結。
總結
綜上所訴,真正影響連結數的操作是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,檔案內容被刪除
相關文章
- Linux---檔案、軟連結於硬連結檔案Linux
- 讀《CSS揭祕》總結一超實用的專案開發技巧CSS
- Linux下的軟連結和硬連結,檔案拷貝的區別Linux
- 【LINUX學習】連結檔案Linux
- 華章揭祕系列精品圖書(《Android應用開發揭祕》、《GWT揭祕》、《Spring技術內幕》)AndroidSpring
- linux下的檔案結構Linux
- 書訊:《Android應用開發揭祕》Android
- LINUX學習(八)Linux檔案連結命令Linux
- 揭祕 YYModel 的魔法(下)
- linux下檔案加密方法總結Linux加密
- ubuntu linux 修改socket最大連線數,同時也是檔案最大開啟數UbuntuLinux
- CSS揭祕實用技巧總結CSS
- linux下軟連結與硬連結Linux
- Linux下的檔案系統結構Linux
- 星環科技分散式檔案系統TDFS大揭祕(上)分散式
- 微信公眾平臺搭建與開發揭祕.pdf
- 揭祕!開發數字資產交易所來運營是如何賺錢的
- 《PHP專案開發案例全程實錄》pdf 附下載連結PHP
- Linux環境下:程式的連結, 裝載和庫[ELF檔案詳解]Linux
- React Fiber 資料結構揭祕React資料結構
- 揭開NTFS下真正的隱藏檔案--'流'的奧秘 (轉)
- 『MySQL』揭開索引神祕面紗MySql索引
- 揭開“QUIC”的神祕面紗UI
- Linux7更改檔案開啟數Linux
- 專案揭祕:送祝福月入過萬
- linux檔案型別和軟硬連結祥析Linux型別
- 使用者指南:Linux 檔案系統的連結Linux
- Linux 下的軟連結Linux
- iOS引用計數管理之揭祕計數儲存iOS
- 不同EXCEL檔案超連結Excel
- 揭祕Java高效隨機數生成器Java隨機
- Facebook開發小遊戲引擎列表(下載連結)遊戲引擎
- Linux-CentOS 最大開啟檔案數和程式數LinuxCentOS
- Omi 多端開發之 - omip 適配 h5 原理揭祕H5
- 揭祕:如何解決短視訊原始碼開發難題!原始碼
- 揭祕亞馬遜雲科技軟體開發工程師團隊亞馬遜工程師
- Linux下原始檔建立硬連結後壓縮原始檔的問題Linux
- JAVA通過URL連結獲取視訊檔案資訊(無需下載檔案)Java