1. 程式人生 > >檔案描述符&檔案指標

檔案描述符&檔案指標

一.檔案描述符(file descriptors 簡稱fd)

   在linux作業系統中開啟或者建立一個檔案就會獲得檔案描述符,那仫什仫是檔案描述符呢?我們知道在linux下

一切皆檔案,檔案描述符是OS為了高效的管理已經被開啟的檔案所建立的一個索引,它是一個很小的正整數,所有執

行I/O操作的系統呼叫都是通過檔案描述符來實現的。

   我們知道一個程序的建立一定會產生對應的pcb(程序控制塊),每個程序的pcb中存在檔案描述符列表,檔案描述

符表中的每個表項都有一個指向已經開啟檔案的指標,檔案描述符就是這個表的索引.

   我們知道在linux系統中定義了三個常見的標準檔案描述符:0(stdin代表標準輸入),1(stdout標準輸出),2(stderr)代表標準錯誤,如果此時再開啟新的檔案,因為0,1,2已經被佔用所以新開啟檔案的檔案描述符只能是3。

  檔案描述符的分配規則:POSIX標準規定,每次開啟檔案時必須使用當前程序的最小可用的檔案描述符號碼.

   深入理解:如果我們將檔案的1號檔案描述符關閉,然後開啟一個檔案file,那仫根據上述的分配規則,這個開啟檔案的檔案描述符就是1。看到這個你想到了什仫?此時如果我們用標準輸出向顯示屏上輸出資訊還會輸出嗎?下面來看一個簡單的栗子:

         

 注意:檔案描述符的分配數量是有範圍的:0~OPEN_MAX-1

如何產生一個檔案描述符

   程序獲取檔案描述符最常見的方法就是通過系統呼叫函式open和create獲取,或者從父程序繼承

   1).從父程序繼承,那仫子程序就可以訪問父程序所使用的檔案。我們知道程序與程序間是互相獨立的,如果有一種情況就是必須使得父子程序之間進行相互通訊,此時這些父子都可以訪問的檔案就成了解決的突破口了

   2).open/create獲取,在linux系統下用man這個命令查詢該系統呼叫的函式

           

三.file結構體

        file結構體的原始碼可參見作業系統中的/kernels/include/linus/fs.h中,核心維護的三種類型的檔案描述符表

1.程序級別的檔案描述符表

       程序級別的檔案描述符表的每一條都記錄了單個檔案描述符的相關資訊,該表中存在如下資訊:控制檔案描述符操作的一組標誌,對開啟檔案控制代碼的引用,這個程序級別的檔案描述符列表用files_struct結構表示,在pcb中有一個該型別的指標變數files.

       file_struct的定義如下:

struct files_struct {
atomic_t count; /* 共享該表的程序數 */
rwlock_t file_lock; /* 保護以下的所有域,以免在tsk->alloc_lock中的巢狀*/
int max_fds; /*當前檔案物件的最大數*/
int max_fdset; /*當前檔案描述符的最大數*/
    int next_fd; /*已分配的檔案描述符加1*/
struct file ** fd; /* 指向檔案物件指標陣列的指標 */
fd_set *close_on_exec; /*指向執行exec( )時需要關閉的檔案描述符*/
fd_set *open_fds; /*指向開啟檔案描述符的指標*/
fd_set close_on_exec_init;/* 執行exec( )時需要關閉的檔案描述符的初 值集合*/
        fd_set open_fds_init; /*檔案描述符的初值集合*/
struct file * fd_array[32];/* 檔案物件指標的初始化陣列*/
};

  2).系統級別的檔案描述符表

   S對所有開啟的檔案有一個系統級別的檔案描述符列表,有的地方也叫做開啟檔案描述符列表,一個開啟檔案控制代碼儲存了這個開啟檔案的全部相關資訊,大概的資訊如下:

1、當前檔案偏移量 
2、開啟檔案時所使用的狀態標識(open中的flags引數) 
3、檔案訪問模式(只讀,只寫,讀寫模式) 
4、與訊號驅動相關的設定。 
5、對該檔案的i-node引用。 
6、檔案型別和訪問許可權。 
7、一個指標、指向該檔案所持有的鎖列表。 
8、檔案的各種屬性,包括檔案大小及不同型別操作相關的時間戳。

3).檔案系統的inode表

   儲存了檔案系統的相關資訊,這三種類型的檔案描述符關係如圖所示:

      

 四.與檔案描述符相關的函式

open:以指定方式開啟一個檔案,呼叫成功後返回一個檔案描述符。 
creat:開啟一個檔案,如果檔案不存在則建立它,成功後返回一個檔案描述符。 
close:關閉檔案,程序對檔案加鎖全部被釋放。 
read:從檔案描述符對應的檔案中讀取檔案,成功後返回讀出的位元組數。 
write:向檔案描述符對應的檔案中寫入資料,成功後返回寫入的位元組數。 
ftruncate:把檔案描述符對應的檔案縮短到指定的長度。 
lseek:把檔案指標設定到指定的位置,相當於庫函式中的fseek。 
fsync:將已經寫入到檔案的資料寫入到磁碟或其他下層裝置中,成功返回0。 
fstat:返回檔案描述符所對應檔案的相關資訊,把結果儲存在struct stat中,成功返回0。 
fchown:修改檔案描述符對應的檔案的檔案所有者和檔案所有者組的資訊。 
fchmod:修改檔案描述符對應的檔案的許可權。 
flock:對檔案施加建議性鎖,成功返回0。 
fcntl:技能施加建議性鎖也能施加強制性鎖,能建立記錄鎖、讀取鎖,寫入鎖,成功返回0 
dup:複製檔案描述符,返回沒有使用的檔案描述符中的最小編號。 
dup2:由使用者指定返回的檔案描述符的值,用來重新開啟或重定向一個檔案描述符。 
select:同時從多個檔案描述符讀取資料或向多個檔案描述符寫入資料。

五.檔案指標

    C語言中使用檔案指標做I/O的控制代碼,檔案指標指向程序使用者中一個被稱為FILE的結構體中,FILE結構中包含一個緩衝區和一個檔案描述符,從某種意義上來說檔案指標就是控制代碼的控制代碼(檔案描述符也被稱為檔案控制代碼).檔案指標在訪問檔案的時候內部是通過檔案描述符實現的,上述輸出重定向的栗子可證明上述觀點。

    在這裡就分享結束啦~~~~