作為檔案系統的抽象,它是io中最基本的概念,所有的磁碟操作都是基於塊進行的。
作業系統效率隨著系統呼叫次數的增多而急劇下降。每次讀寫操作位元組數太少,會導致讀寫次數增多而降低效率;每次讀寫不是塊大小的整數倍,也會因為對齊資料而降低效率。
系統呼叫stat可以輕鬆指定裝置的塊大小。
現實中程式很少以塊為單位進行操作,程式往往是以區域、行和單個字元為單位進行操作。為了改善這種情況,程式使用使用者緩衝io。當資料寫入時,它會被儲存在程式位址空間的緩衝區中。當緩衝區達到乙個給定的值,整個緩衝區會在一次操作中被寫出。同理,讀操作一次讀入緩衝區大小且塊對齊的資料。當應用程式執行不對齊的讀請求時,緩衝區一塊一塊的給出資料。最後,當緩衝區為空時,另乙個大的塊對齊的區域又被讀入。
乙個程式究竟應該使用標準io或是自創的使用者緩衝,還是直接使用系統呼叫,這些都需要設計者仔細權衡程式的需求和行為後決定。
在標準io中,乙個開啟的檔案叫做「流」(其實流就是乙個指向file的指標??)。
檔案通過fopen開啟以供讀寫操作。引數mode描述以怎樣的方式開啟指定檔案。它可以是以下的字串之一:r、r+、w、w+、a、a+。
函式fdopen將乙個已經開啟的檔案描述符轉成乙個流。
fclose函式關閉乙個給定的流。fcloseall函式關閉所有的和當前程序相關聯的流,包括標準輸入、標準輸出、標準錯誤。
c標準庫實現了多種從流中讀取資料的方法。其中最常用的是三種:單位元組的讀取、單行的讀取、和二進位制資料的讀取。
fgetc可以用來從流中讀取單個字元。這個函式從流中讀取下乙個字元並把該無符號字元強制轉換為int型返回。ungetc允許程式設計師**流,如果你不需要該字元時,可以把它放回。如果多個字元被放入流中,它們會以倒序的方式返回。
函式fgets從乙個給定的流中讀取乙個字串。這個函式從流中讀取size-1個字元到str中,當所有字元讀入時,空字元被存入字串末尾。當讀到eof或者換行符時讀入結束。如果讀到乙個換行符,「\n」被存入str。
呼叫fread用來讀二進位制資料。
所有的機器設計都有資料對棄的要求。c變數的儲存和訪問都要是位址對齊的。在處理結構體,手動執行記憶體管理,向磁碟儲存二進位制資料,進行網路通訊時,對齊都非常重要。
函式fputc用來寫入單個字元。函式fputs用來往給定的流中寫入乙個完整的字串。fwrite函式用來寫入二進位制資料。
函式fseek是標準io最常用的定位函式,操縱流指向檔案中由offset和whence指定的位置。函式fsetpos將流的位置設定到pos處。函式rewind將位置重置到流的初始位置,並且清空錯誤標記。ftell函式返回當前流的位置。標準輸入輸出還提供了fgetpos函式,成功時,fgetpos返回0,並且將當前流的位置設定為pos。
標準io庫提供了fflush函式,將使用者緩衝區寫入核心,並且保證所有的資料都通過write寫出。如果stream是空的,所有程序開啟的流會被清洗掉。
本章所提到的所有呼叫的緩衝區都是通過c函式庫來維護的,他們保留在使用者空間中,而不是核心空間。這樣可以提高效率,程式保留在使用者空間中,並且執行使用者的**,不執行系統呼叫。只有當磁碟或者其他介質必須被訪問時系統呼叫才會被執行。fflush只是把使用者緩衝的資料寫入到核心緩衝區。這並不保證資料能夠寫入物理介質。
函式ferror測試是否在流上設定了錯誤標誌,錯誤標誌由其它響應錯誤的標準io函式設定。函式feof測試檔案結尾標誌是否被設定。函式clearerr為流清空錯誤和檔案結尾標誌。
函式fileno用來獲得流的檔案描述符。
標準io實現了三種使用者緩衝,而且為開發者提供了乙個用來控制緩衝區大小和型別的介面:
不緩衝:沒有執行使用者緩衝,資料直接提交到核心。標準錯誤預設是不緩衝的。
行緩衝:緩衝以行為單位執行。
函式setvbuf設定流的緩衝型別模式。
執行緒的定義是共享同一位址空間的多個程序。如果不採取資料同步措施或將資料線程私有化,執行緒可以任何時間修改共享資料。支援執行緒的作業系統提供加鎖機制(保證相互排斥的程式結構)來保證執行緒不會互相干擾。
標準io的函式本質上是執行緒安全的。在內部實現中,設定了一把鎖,乙個鎖計數器,和為每個開啟的流建立的所有者執行緒。乙個執行緒要想執行任何io請求,必須首先獲得鎖而且成為所有者執行緒。
當然在實際應用中,許多應用程式需要比單獨的函式呼叫更強的原子性。
函式flockfile會等待流被解鎖,然後獲得鎖,增加鎖計數,成為流的所有者執行緒,然後返回。
函式funlockfile減少與流相關的鎖計數。
如果鎖計數器達到了0,當前的執行緒放棄流的所有權,另乙個執行緒現在能獲得鎖。
函式ftrylockfile是flockfile的非堵塞版本。如果流當前加了鎖,ftrylockfile不做任何處理,並立即返回乙個非零值。如果流當前沒有加鎖,它獲得鎖,增加鎖計數,成為流的所有者執行緒,並且返回0。
linux提供了一些不加鎖的標準io函式,這些函式類似通常的標準io函式,但是不執行任何鎖操作。這樣可以通過程式設計師的手動加鎖,來提高執行的效率。
Linux系統程式設計(第三章)筆記
由於塊是檔案系統中最小儲存單元的抽象,在核心中,所有檔案系統操作都是基於塊來執行。因此所有i o操作都是在塊大小或者塊大小的整數倍上執行。假設要讀取1024個位元組,每次讀乙個位元組需要1024次呼叫,而如果乙個讀取1024位元組的塊則只需要呼叫一次。對於這種提公升其效能的途徑是 使用者緩衝i o ...
Linux系統程式設計 第三章 緩衝輸入輸出
1 使用者緩衝io 在使用者空間實現的緩衝區,用於將程式的多次輕量級的io請求組合起來,提高操作效率。2 標準io 屬於c語言標準庫,因此檔案開啟,關閉,讀寫都是通過標準io庫完成的。3 檔案指標 file 在c標準庫中,不屬於核心,實際上對映到核心的檔案描述符 4 檔案操作 一下提到的緩衝區是由c...
程式設計珠璣第三章
第三章寫的有點太簡單了,可能作者是想在後面章節裡再詳細說吧!這一章就是作者說的幾句話印象還是很深刻。程式設計師在節省空間方面無計可施時,將自己從 中解脫出來,退回起點並記者並集 中精力研究資料,常常能有奇效。資料的 表示形式是程式設計的根本。正如人月神話的作者說 只要給我你設計的表,我就對你的程式一...