文件描述符(fd)與FILE結構體

文件描述符

內核(kernel)利用文件描述符(file descriptor)來訪問文件。文件描述符是非負整數。打開現存文件或新建文件時,內核會返回一個文件描述符。讀寫文件也需要使用文件描述符來指定待讀寫的文件。

我們知道,在Linux中有一個說法:一切皆文件,而文件描述符又是內核訪問文件的橋樑,可以想象文件描述符的重要程度。

既然文件描述符是一個非負整數,那麼到底是幾呢?又有什麼規律可循呢?

首先我們可以創建一個新的文件,然後看它的文件描述符是多少,我們發現,是3,再一次創建幾個,我們發現文件描述符是從3按每次加一的規律一次排的。這個時候我們會想到,那麼0,1,2呢?

實際上,當我們將一個程序從硬盤加載到內存後,這個程序就化身爲了一個進程,這時系統會默認打開三個文件: 標準輸入(stdin)、標準輸出(stdout)、標準錯誤(stderr)。這三個文件相對應的三個文件描述符分別爲0、1、2。

但是這就是文件描述符的規律了嗎?是,但是不完整。

我們剛連續創建了幾個文件,假設有3個吧,分別是file1,file2,file3,那麼當我們吧file2刪除了,再創建file4的時候,那麼,file4的文件描述符是多少呢?

按照前面我們總結的規律來說,應該是6吧,但是,實際是4,回想一下,4是原來file2的文件描述符,但是file2刪除之後,4這一塊就空下來了,那麼新創建的文件,就放進來了。

所以總結一下:分配文件描述符是從最小的未被使用的開始

文件與進程的關係:

文件描述符其實是文件描述符表的下標:

這裏寫圖片描述

說到這,我們就來回顧一下,我們一直沒有注意的地方。

FILE到底是什麼類型

我們那先學的類型,在學的類型指針,但是有一個是例外的,FILE*(文件指針),一直都沒有了解過FILE是什麼類型,不知道你們瞭解過沒有,不過,不管有沒有,今天在這都要了解一下。

FILE

FILE其實是一個結構體,也就是前面畫的那一個圖中的file_struct,其中文件描述符是這個結構體的一個成員。

我們學C語言的時候,一般通過FILE*來訪問文件,現在又知道了fd,那麼這兩個之間有什麼聯繫與區別呢?

1、文件指針指向一個FILE結構體,而此結構體中包含一個成員叫做文件描述符(fd)

2、文件描述符是整數,

3、fd是內核訪問文件的橋樑;在C庫中,f系列只認文件指針

我們已經知道了FILE的一個成員是文件描述符了,那麼其它的成員呢?

struct _iobuf {  

    char *_ptr; //文件輸入的下一個位置  
    int _cnt; //當前緩衝區的相對位置  
    char *_base; //指基礎位置(即是文件的其始位置)  
    int _flag; //文件標誌  
    int _file; //文件描述符  
    int _charbuf; //檢查緩衝區狀況,如果無緩衝區則不讀取  
    int _bufsiz; //緩衝區大小  
    char *_tmpfname; //臨時文件名  

        };  
typedef struct _iobuf FILE; 

files_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];/* 文件對象指針的初始化數組*/
};
struct file
{
struct list_head f_list; /*所有打開的文件形成一個鏈表*/
struct dentry *f_dentry; /*指向相關目錄項的指針*/
struct vfsmount *f_vfsmnt; /*指向VFS安裝點的指針*/
struct file_operations *f_op; /*指向文件操作表的指針*/
mode_t f_mode; /*文件的打開模式*/
loff_t f_pos; /*文件的當前位置*/
unsigned short f_flags; /*打開文件時所指定的標誌*/
unsigned short f_count; /*使用該結構的進程數*/
unsigned long f_reada, f_ramax, f_raend, f_ralen, f_rawin;
/*預讀標誌、要預讀的最多頁面數、上次預讀後的文件指針、預讀的字節數以及
預讀的頁面數*/
int f_owner; /* 通過信號進行異步I/O數據的傳送*/
unsigned int f_uid, f_gid; /*用戶的UID和GID*/
int f_error; /*網絡寫操作的錯誤碼*/

unsigned long f_version; /*版本號*/
void *private_data; /* tty驅動程序所需 */

};

file結構體的幾個重要的成員變量:

1、f_flags:表示打開文件的權限 。
2、f_pos:表示當前讀寫文件的位置。
3、f_count:表示打開文件的引用計數,如果有多個文件指針指向它,就會增加f_count的值。
4、f_mode:設置對文件的訪問模式,例如:只讀,只寫、可讀可寫等。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章