日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

文件描述符与打开文件的关系

發布時間:2023/11/30 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 文件描述符与打开文件的关系 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

所有執行I/O操作的系統調用都以文件描述符,即一個非負整數來指代所打開的文件。文件描述符可以用來表示所有類型的已打開文件。同時,多個文件描述符可以指向同一個打開文件,因為有在不同進程中打開同一個文件的需求。

那么,系統是如何維護硬盤文件與文件描述符之間的聯系呢?

要理解具體的情況如何,需要查看由內核維護的3個數據結構:

  • 進程級的文件描述符
  • 系統級的打開文件表
  • 文件系統的i-node表
針對每個進程,內核為其維護打開文件的描述符(open file descriptor)表。該表的每一項都記錄了單個文件描述符的相關信息,如下所示:
  • 控制文件描述符操作的一組標志(目前僅定義了一個,即close-on-exec標志)
  • 對打開文件句柄的引用
內核對所有打開的文件維護一個系統級的描述表格(open file description table)。也叫打開文件表(open file table),表中的每一項稱為打開文件句柄(open file handle)。一個打開文件句柄存儲了與一個打開文件相關的全信息,如下:
  • 當前文件偏移量(調用read()和write()時更新,或使用lseek()直接修改)
  • 文件的訪問模式(如調用read()時設置的只讀模式、只寫模式等)
  • 與信號驅動I/O相關的設置
  • 對該文件i-node對象的引用
同時,文件系統又會對每個存儲其上的文件建立一個i-node表。這里只給出i-node表的信息:
  • 文件類型(如常規文件、套接字或FIFO)和訪問權限
  • 一個指針,指向該文件所持有的的鎖的列表
  • 文件的各種屬性,包括文件大小以及不同類型操作相關的時間戳
下圖展示了這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),那么從另一個文件描述符中也會得到相應的改變。不管這兩個文件描述符是分別屬于同一進程還是不同的進程;
  • 要獲取和修改打開的文件標志(如O_APPEND、O_NONBLOCK等),可以執行fcntl()的F_GETFL和F_SETFL操作,其對作用域的約束與上一條類似;
  • 相比之下,文件描述符標志(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”。

    程序運行結果如下:


    結果證實了我們的討論。

    總結

    以上是生活随笔為你收集整理的文件描述符与打开文件的关系的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。