linux檔案描述符,系統開啟檔案和i節點的關係
阿新 • • 發佈:2019-01-25
首先區分檔案描述符和開啟的檔案
核心維護了三個資料結構
程序級的檔案描述符表(即每個程序一個)
系統級的開啟檔案表(即該表在整個核心中只有一個)
檔案系統的 i-node 表
針對每個程序,核心為其維護一個開啟的檔案描述符表(open file descriptor table),改表的每一項都記錄了單個檔案描述符的相關資訊,如下:
控制檔案描述符的操作的一組標識,目前只定義了一個,即 close-on-exec 標識
對開啟檔案控制代碼的引用
系統為所有開啟的檔案維護了一個系統級別的描述表格(open file description table)。該表的每一項儲存了一個已開啟的檔案的所有相關資訊,包括如下內容:
檔案指標偏移量 (read()和write()修改,以及lseek()修改)
開啟檔案的狀態標識
檔案訪問模式
與訊號驅動I/O相關的設定
指向 i-node 物件的一個指標
這裡有兩個概念要區分
一個是檔案描述符標識,一個是檔案標識。顯然,檔案描述符標識是標識檔案描述符的特性,檔案標識是標識檔案的特性。close-on-exec是檔案描述符的標識。O_APPEND 是檔案標識。並且檔案描述符標識體現在程序檔案描述符表結構中。檔案狀態標識體現在系統開啟檔案描述符表中。
每個檔案系統都有一個i-node結構,包括如下資訊:
檔案型別和許可權,例如regular file,socket等
該檔案持有的所有鎖
其他各種特性,比如檔案大小,時間戳等等
1. 對同一個檔案描述符的讀和寫位置共享。
測試程式碼:
char buf[128];
int main(int argc,char *argv[])
{
char *s = "test";
int fd = open("test.txt",O_RDWR);
if(fd == -1)
{
perror("open test.txt failure");
exit(EXIT_FAILURE);
}
int readNum = read(fd,buf,3);
write(fd,s,4);
if(-1 == close(fd))
{
perror("close failure");
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}
測試條件,test.txt檔案的初始內容為123456789
測試結果:程式執行之後test.txt檔案的內容為123test89
分析:
1. 對 test.txt 進行了讀寫開啟
2. 先對test.txt 讀3個位元組,所以此時fd的偏移量應該是3
3. 接著對fd寫4個位元組,根據最終的輸出結果可以知道此時是從偏移量為3的地方開始寫的,所以對於同一個檔案描述符來說,讀寫位置是共享的。
2. 同一個程序多次開啟同一個檔案
測試程式碼:
int main(int argc,char *argv[])
{
char buf[10];
char *s = "test";
int fd1 = open("test.txt",O_RDWR);
int readNum = read(fd1,buf,3);
int fd2 = open("test.txt",O_RDWR);
write(fd2,s,4);
}
測試條件,test.txt檔案的初始內容為123456789
測試結果:程式執行之後test.txt檔案的內容為test56789
分析:
1. 對 test.txt 進行了第一次open操作得到fd1
2. 先通過fd1對test.txt 讀3個位元組,所以此時fd1所對應的偏移量應該是3
3. 接著對test.txt進行了第二次open操作,得到了fd2,
4. 通過fd2對test.txxt寫4個位元組,根據最終的輸出結果可以知道此時是從偏移量為0的地方開始寫的
5. 綜上所述,如果對同一個檔案開啟多次,那麼這些檔案描述符所對應的核心結構是獨立的。
6、從上面的結果也可以看出來,即使是同一個檔案,如果我們打開了多次,那麼核心也會維護多個開啟檔案表項。