檔案與輸入輸出

檔案描述符(file descriptor)

想像衣帽間的櫃台。你交出外套,換回一張小小的號碼牌。號碼牌不是外套——它是個替身,之後你拿它出來說「把我先前交給你的那件還我」。檔案描述符就是那張號碼牌。當你的程式開啟一個檔案時,作業系統做真正的工作去找到並追蹤它,然後遞回給你一個小小的整數。從此以後你不再傳遞檔案本身——你傳遞的是那個數字。

具體來說,檔案描述符是一個小的非負整數,通常從 0、1、2 開始往上數。它是核心為每個行程所保存的一張表(見「檔案描述符表」)的索引,表中每個格子指向核心對某個已開啟檔案的真實記錄。你從 open() 拿到它,再把它交給 read()、write()、lseek()、close(),用來說明你指的是哪個已開啟的檔案。依照長久以來的慣例,0 是標準輸入、1 是標準輸出、2 是標準錯誤,所以一個剛啟動的程式早已開好了這三個描述符。描述符指稱的不只是磁碟上的檔案:管線、通訊端、裝置與終端機,也都以描述符的形式出現。

為何重要:檔案描述符是 Unix I/O 的核心把手。幾乎每一個搬移位元組進出的系統呼叫,第一個引數都是 fd。這個數字只在擁有它的行程內部有意義——你程式裡的 fd 3 和我程式裡的 fd 3 指的是完全不同的東西。也正因為它只是個小整數索引,複製、儲存、傳給子行程都很便宜,而這正是重導向與管線得以成立的關鍵。

int fd = open("notes.txt", O_RDONLY); /* fd 可能是 3 */ char buf[64]; ssize_t n = read(fd, buf, sizeof buf); close(fd);

open() 回傳小整數 3;之後每個呼叫都用這個數字、而不是路徑來指稱該檔案。

描述符只是一個索引,不是檔案本身。兩個描述符可以指向同一個已開啟的檔案,關掉其中一個不會影響另一個;只有當最後一個參考被關閉時,核心才真正釋放底下的開啟檔案。

又稱
fdfd(檔案描述子)