檔案描述符與開啟檔案的關係

2021-07-07 07:28:27 字數 1925 閱讀 1792

所有執行i/o操作的系統呼叫都以檔案描述符,即乙個非負整數來指代所開啟的檔案。檔案描述符可以用來表示所有型別的已開啟檔案。同時,多個檔案描述符可以指向同乙個開啟檔案,因為有在不同程序中開啟同乙個檔案的需求。

那麼,系統是如何維護硬碟檔案與檔案描述符之間的聯絡呢?

要理解具體的情況如何,需要檢視由核心維護的3個資料結構:

核心對所有開啟的檔案維護乙個系統級的描述**(open file description table)。也叫開啟檔案表(open file table),表中的每一項稱為開啟檔案控制代碼(open file handle)。乙個開啟檔案控制代碼儲存了與乙個開啟檔案相關的全資訊,如下:

同時,檔案系統又會對每個儲存其上的檔案建立乙個i-node表。這裡只給出i-node表的資訊:

下圖展示了這3個資料結構之間的關係。在下圖中,兩個程序擁有諸多開啟 的檔案描述符:

在程序a中,檔案描述符1和20都指向同乙個開啟的檔案控制代碼23,這可能是通過呼叫dup、dup2或fcntl形成的。

程序a的檔案描述符2和程序b的檔案描述符2都指向同乙個開啟的檔案控制代碼73,這可能是呼叫fork之後出現的。或者某程序通過unix域套接字將乙個開啟的檔案描述符傳遞給另乙個程序。

此外,程序a的檔案描述符0和程序b的檔案描述符3分別指向不同的開啟檔案控制代碼,但這些開啟檔案控制代碼指向同乙個i-node表中的相同條目。可能是兩個程序各自對同乙個檔案呼叫open開啟。同時,在乙個程序中兩次開啟同乙個檔案,也會出現這種情況。

這裡我們可以得到一些結論:

兩個不同的檔案描述符,若指向同乙個檔案開啟控制代碼,將共享同一檔案的偏移量。因此,如果通過其中乙個檔案描述符來修改檔案偏移量(呼叫open、write、lseek),那麼從另乙個檔案描述符中也會得到相應的改變。不管這兩個檔案描述符是分別屬於同一程序還是不同的程序;

相比之下,檔案描述符標誌(close-on-exec標誌)為程序和檔案描述符所私有,對這一標誌的修改將不會影響同一程序或不同程序中的其他檔案描述符。

下面給出具體的例項驗證上面的討論。

fd1=open(file,o_creat | o_rdwr | o_trunc,s_irusr | s_iwusr);

fd2=dup(fd1);

fd3=open(file,o_rdwr);

write(fd1,"hello",6);

write(fd2,"world",6);

lseek(fd2,0,seek_set);

write(fd1,"hello",6);

write(fd3,"yellow",6);

上面的**中有三個檔案描述符,都是開啟同乙個檔案,即共享同乙個i-node項。不同的是fd2通過呼叫dup複製檔案描述符fd1,因此fd1與fd2共享同乙個檔案開啟控制代碼。fd3是同乙個程序中另乙個open操作,因此和fd1對比,兩個檔案描述符指向不同的檔案開啟控制代碼,但指向同乙個i-node專案。下圖展示了它們的關係:

因此,對fd1和fd2的open、write、lseek等操作會使檔案偏移量發生改變。fd1寫入「hello」之後,檔案偏移量變為6,fd2寫入時在6之後寫入,此時檔案中的內容是「helloworld」;

當fd2呼叫lseek改變檔案偏移量為0,之後fd1寫入檔案,是在偏移量為0的基礎上寫入,因此覆蓋最初的6位元組,檔案內容變為「helloworld」;對於fd3,因為與fd1和fd2指向不同的檔案開啟控制代碼,因此fd1和fd2的操作不影響fd3指向的檔案開啟控制代碼的檔案偏移量,所以fd3寫入時會覆蓋最初的6位元組,此時檔案內容變為「yelloworld」。

程式執行結果如下:

結果證實了我們的討論。

linux檔案描述符與開啟檔案的關係

1.概述 在linux系統中一切皆可以看成是檔案,檔案又可分為 普通檔案 目錄檔案 鏈結檔案和裝置檔案。檔案描述符 file descriptor 是核心為了高效管理已被開啟的檔案所建立的索引,其是乙個非負整數 通常是小整數 用於指代被開啟的檔案,所有執行i o操作的系統呼叫都通過檔案描述符。程式剛...

linux檔案描述符與開啟檔案之間的關係

1.概述 在linux系統中一切皆可以看成是檔案,檔案又可分為 普通檔案 目錄檔案 鏈結檔案和裝置檔案。檔案描述符 file descriptor 是核心為了高效管理已被開啟的檔案所建立的索引,其是乙個非負整數 通常是小整數 用於指代被開啟的檔案,所有執行i o操作的系統呼叫都通過檔案描述符。程式剛...

檔案描述符和開啟檔案之間的關係

在linux系統中一切都可以看作是檔案,檔案又分為 普通檔案 目錄檔案 鏈結檔案和裝置檔案。檔案描述符是核心為了高效管理已被開啟的檔案所建立的索引,起值是乙個非負整數,用於指代被開啟的檔案,所有執行i o操作的系統呼叫都通過檔案描述符。每乙個檔案描述符會與乙個開啟檔案相對應,同時,不同的檔案描述符也...