Linux標準IO與檔案IO的區別與聯絡

2021-10-24 02:26:41 字數 3331 閱讀 1177

本文主要內容是從網上摘錄的,將查到的零散資訊消化後歸納在一起,方便以後查閱。

linux探秘之i/o效率

linux系統程式設計之基礎必備(四):c 標準庫io緩衝區和核心緩衝區的區別     

標準i/o:是指標準i/o庫,又稱帶快取的i/o。它由ansi c標準說明,標準i/o庫代替使用者處理很多細節,比如快取分配、以優化長度執行i/o等,提供快取的目的是為了儘量減少read和write的呼叫次數。

常用函式:fopen、fread、fwrite、fclose、printf、fprintf、scanf、sscanf等。

檔案i/o:又被稱為不帶緩衝的i/o,指的是每個read和write都是呼叫核心中的乙個系統呼叫。這些不帶緩衝的檔案i/o函式不是iso c的組成部分。它們是posix.1和single unix specification的組成部分。常用函式:open、read、write、lseek、close等。

使用者程式呼叫c標準i/o庫函式讀寫普通檔案或裝置,而這些庫函式要通過系統呼叫把讀寫請求傳給核心 ,最終由核心驅動磁碟或裝置完成i/o操作。c標準庫為每個開啟的檔案分配乙個i/o緩衝區以加速讀寫操作,通過檔案的file 結構體可以找到這個緩衝區,使用者呼叫讀寫函式大多數時候都在i/o緩衝區中讀寫,只有少數時候需要把讀寫請求傳給核心。以fgetc  / fputc 為例,當使用者程式第一次呼叫fgetc 讀乙個位元組時,fgetc 函式可能通過系統呼叫 進入核心讀1k位元組到i/o緩衝區中,然後返回i/o緩衝區中的第乙個位元組給使用者,把讀寫位置指 向i/o緩衝區中的第二個字元,以後使用者再調fgetc ,就直接從i/o緩衝區中讀取,而不需要進核心 了,當使用者把這1k位元組都讀完之後,再次呼叫fgetc 時,fgetc 函式會再次進入核心讀1k位元組 到i/o緩衝區中。在這個場景中使用者程式、c標準庫和核心之間的關係就像在「memory hierarchy」中 cpu、cache和記憶體之間的關係一樣,c標準庫之所以會從核心預讀一些資料放  在i/o緩衝區中,是希望使用者程式隨後要用到這些資料,c標準庫的i/o緩衝區也在使用者空間,直接 從使用者空間讀取資料比進核心讀資料要快得多。另一方面,使用者程式呼叫fputc 通常只是寫到i/o緩 沖區中,這樣fputc 函式可以很快地返回,如果i/o緩衝區寫滿了,fputc 就通過系統呼叫把i/o緩衝 區中的資料傳給核心,核心最終把資料寫回磁碟或裝置。有時候使用者程式希望把i/o緩衝區中的資料立刻  傳給核心,讓核心寫回裝置或磁碟,這稱為flush操作,對應的庫函式是fflush,fclose函式在關閉檔案 之前也會做flush操作。

1、緩衝機制區別:

眾所周知,cpu和記憶體的資料交換要遠大於磁碟操作,通過快取機制,可以減少磁碟讀寫的次數,提高併發處理程式的效率,因此,快取是一種提高任務儲存和處理效率的有效方法。

從巨集觀上看,linux作業系統分為使用者態和核心態,在處理i/o操作的時候,兩者都提供了快取。使用者態的稱為標準i/o快取,也稱為使用者空間快取,而核心態的稱為緩衝區快取記憶體,也叫頁面快取記憶體。既然都提供了快取,那為什麼這本書上卻分不帶i/o的快取和帶i/o的快取,原因其實是「不帶i/o快取」指的是使用者空間中不為這些i/o操作設有緩衝,而核心是帶緩衝的。

2、i/o操作的流程區別:

如上圖所示,使用者程序空間和核心程序空間讀寫磁碟的操作都要經過緩衝區快取,快取的作用前面也提到過,是為了減少磁碟讀寫的次數,提高i/o的效率。當讀寫乙個檔案時,首先看系統i/o的操作流程。

2.1 檔案i/o:

屬於核心系統呼叫,沒有涉及使用者態的參與。以圖中標號為例:

(3) 呼叫write函式向檔案中寫資料,buf中存放的就是要寫入的資料,如write(fd, 'abc', 3)。呼叫前需要先設定buffsize。不同的buffsize會影響i/o效率,下面再來說這個問題。

(5) 延遲寫:當快取區快取記憶體滿或者核心要重寫緩衝區的時候,才將資料寫入輸出佇列,等資料到佇列首部的時候,才真正觸發磁碟的寫操作。

(6) 預讀:當檢測到正進行順序讀取時,核心就試圖讀入比應用程式所要求更多的資料,並假想應用程式很快就會讀到這些資料。這樣,當緩衝區沒有資料時,能夠快速填充下次要讀取的資料。

(4) 呼叫read從緩衝區快取記憶體讀取所需資料到邏輯單元中進行處理。

以上,就是系統i/o所涉及到的四步操作。

2.2 標準i/o:

屬於iso c實現的標準庫函式,呼叫的是底層的系統呼叫。

(1) 將邏輯單元中的資料寫入檔案,根據需求,有三種函式型別可以呼叫,以fputc、fputs、fwrite為例,這些函式不用人為去控制緩衝區的大小,而是系統自動申請的,當使用者定義了相應的i/o函式之後,根據不同的快取型別(是全緩衝、行緩衝還是無緩衝),系統自動呼叫malloc等函式申請緩衝區,即標準i/o快取。

(3)(5) 當使用者緩衝區滿了之後,如系統i/o操作一般,此時呼叫write從標準i/o快取中複製資料到核心緩衝區,再寫入磁碟。

(4)(6) 同系統i/o操作,從核心緩衝區呼叫read讀入到使用者緩衝區。

(2) 同樣有三種函式型別可以呼叫,以fgetc、fgets、fread為例,讀入邏輯單元進行後續的處理。

可見,標準i/o實現的機制就是基於系統i/o,這樣看來,標準i/o在效率上肯定不如系統i/o,但事實是標準i/o與系統i/o相比並不慢很多,而且還有很多其他的優點。

2.3 用資料流來形容兩者的差異:

無快取i/o操作的資料流:資料->核心快取區->磁碟

標準i/o操作的資料流:資料->流快取區->核心快取區->磁碟

2.4 標準i/o的優點和缺點:

1)使用標準i / o例程的乙個優點是無需考慮快取及最佳i / o長度的選擇,並且它並不比直接呼叫read、write慢多少

2)在標準i / o庫中,乙個效率不高的不足之處是需要複製的資料量。當使用每次一行函式fgets和fputs時,通常需要複製兩次資料:一次是在核心和標準i / o快取之間(當呼叫read和write時),第二次是在標準i / o快取(通常系統分配和管理)和使用者程式中的行快取(fgets的引數就需要乙個使用者行快取指標)之間。

3、經典回答:

前者屬於低階io,後者是高階io。

前者返回乙個檔案描述符(使用者程式區的),後者返回乙個檔案指標。

前者無緩衝,後者有緩衝。

前者與 read, write 等配合使用, 後者與 fread, fwrite等配合使用。

後者是在前者的基礎上擴充而來的,在大多數情況下,用後者。

上面就是open和fopen的區別介紹了,兩者的區別主要是緩衝的區別,fopen有緩衝而open沒有,還有它們的層次也有所不同,fopen可移植而open不能。

檔案標準標準IO與檔案IO 的區別

首先宣告,我是乙個菜鳥。一下文章中出現技術誤導情況蓋不負責 先來了解下什麼是標準 以及檔案 標準 標準i o是ansi c建立的乙個標準i o模型,是乙個標準函式包和stdio.h標頭檔案中的定義,擁有必定的可移植性。標準io庫處理很多細節。例如快取分配,以優化長度執行io等。標準的io供給了三種型...

標準IO與檔案IO 的區別

先來了解下什麼是標準 以及檔案 標準 標準i o是ansi c建立的乙個標準i o模型,是乙個標準函式包和stdio.h標頭檔案中的定義,具有一定的可移植性。標準io庫處理很多細節。例如快取分配,以優化長度執行io等。標準的io提供了三種型別的快取。1 全快取 當填滿標準io快取後才進行實際的io操...

標準IO與檔案IO 的區別

先來了解下什麼是標準 以及檔案 標準 標準i o是ansi c建立的乙個標準i o模型,是乙個標準函式包和stdio.h標頭檔案中的定義,具有一定的可移植性。標準io庫處理很多細節。例如快取分配,以優化長度執行io等。標準的io提供了三種型別的快取。1 全快取 當填滿標準io快取後才進行實際的io操...