Linux 檔案描述符的概念及與檔案流指標的關係

2021-10-22 09:57:29 字數 2279 閱讀 7042

我們都知道,使用open開啟乙個檔案後都會得到乙個檔案描述符,而且是乙個非負正數,那這個數字是怎麼來的呢?

當我們打使用open開啟檔案時,系統會為我們指定的檔案建立乙個檔案描述資訊結構體(struct file),用來描述檔案所在的位址及名稱等資訊,而在我們的程序中,還儲存了乙個檔案資訊表(struct files_struct),檔案資訊表中有乙個結構體陣列(struct file *fd arry),是用來儲存檔案描述資訊的位址,而檔案描述資訊的位址所在的下標,就是檔案描述符。

當我們使用檔案描述符去讀寫檔案時,會通過檔案描述符去檔案資訊表下的結構體陣列對應的下標獲得到相應的位址,再通過位址找到檔案描述資訊,從而找到在磁碟中我們想要的那個檔案

流程圖如下:

所以我們每次開啟乙個檔案,不操作了就需要close關閉並釋放資源;結構體陣列大小是有限的,下標也就是有限的,若不關閉檔案,檔案描述符用完了,那麼在程序中就無法開啟新的檔案了。

細心的小夥伴會發現為什麼每次檔案識別符號都會從3開始的,其實只要乙個程式被執行起來,程序就會被預設開啟3個檔案,0-標準輸入;1-標準輸出; 2-標準錯誤

檔案描述符分配規則:最小未使用—從陣列0號下標開始找到未使用的下標分配給新的檔案

假如我們把0號檔案關閉了,那麼我們再開啟乙個檔案時,它的檔案描述符就會成為0。

那假如我們關閉了1號檔案描述符,會是怎樣的結果呢?

我們發現並沒有列印任何東西,原因是printf函式時列印資料到標準輸出,也就是將資料寫到1號檔案描述符中,也就是當前的標準輸出流中,標準輸出流再將其列印;但是如果close(1)後,再開啟乙個新檔案,那麼新檔案會占用1號這個位置,printf函式就不會直接列印資料,而是在重新整理緩衝區之後將資料寫到了新的檔案中

這其實就是重定向的乙個典型例子,重定向原理:將資料不再寫入原本的檔案,而是寫入新的指定的檔案中,實現方式就是替換這個檔案描述符對應的檔案描述資訊;說到底就是檔案描述符的重定向,改變描述符所指的檔案,就改變了資料的流向。

在我們庫函式中,也有重定向的函式–int dup2(int oldfd, int newfd)–讓newfd這個描述符也指向oldfd所指向的檔案,這時候oldfd和newfd都能操作oldfd所指向的檔案

這樣子就能做到1個描述符能操作兩個檔案了

例項:實現乙個帶有重定向功能的shell

檔案描述符:是乙個非負正數 —系統呼叫的io介面

檔案流指標:file結構體 —typedef struct_io_file file --庫函式io介面的操作控制代碼

我們知道庫函式封裝了系統呼叫介面,底層最終還是會呼叫系統呼叫介面的,通過檔案流指標進行檔案操作的時候,依然還是要能夠找到檔案對應的檔案描述符才行

檔案流指標是乙個結構體,結構體中有很多成員變數,其中_fileno為檔案描述符

現在我們改變我們開啟的檔案的檔案描述符,讓該檔案描述符變為1

#include

#include

#include

intmain()

我們發現並沒有將檔案寫到test.txt檔案中,而是將內容列印出來

在我們想向檔案寫入資料時,並不會直接寫入檔案,而是先寫入到緩衝區,重新整理緩衝區的時候才會寫入檔案。系統呼叫介面是直接將資料寫到檔案中,系統呼叫介面是沒有緩衝區的,只有庫函式才有這個緩衝區,而這個緩衝區是在檔案流指標結構體中的緩衝區–通常稱為使用者態緩衝區

linux中的檔案描述符概念

1.檔案描述符 檔案描述符,file descriptor,簡稱fd。檔案描述符在形式上是乙個非負整數。實際上,它是乙個索引值,指向核心為每乙個程序所開啟檔案的記錄表。當程式開啟乙個現有檔案或者建立乙個新檔案時,核心向程序返回乙個檔案描述符。在程式設計中,一些涉及底層的程式編寫往往會圍繞著檔案描述符...

linux檔案描述符

本文介紹了檔案描述符,1 首先說什麼是檔案描述符,它有什麼作用?檔案描述符是乙個簡單的整數,用以標明每乙個被程序所開啟的檔案和socket。基於檔案描述符的輸入輸出函式 open 開啟乙個檔案,並指定訪問該檔案的方式,呼叫成功後返回乙個檔案描述符。creat 開啟乙個檔案,如果該檔案不存在,則建立它...

linux檔案描述符

當某個程式開啟檔案時,作業系統返回相應的檔案描述符,程式為了處理該檔案必須引用此描述符。所謂的檔案描述符是乙個低階的正整數。最前面的三個檔案描述符 0,1,2 分別與標準輸入 stdin 標準輸出 stdout 和標準錯誤 stderr 對應。因此,函式 scanf 使用 stdin,而函式 pri...