Linux高階程式設計 05 檔案讀寫

2022-07-08 18:42:21 字數 1583 閱讀 7934

檔案讀寫主要牽涉到了如下五個操作:開啟、關閉、讀、寫、定位。在linux系統中,提供了兩套api,

其中posix定義的api是系統api,而c標準api是基於系統api的封裝,並且提供了額外的緩衝的功能。因此也可以把它們叫做緩衝i/o函式和非緩衝i/o函式。

除了前面介紹的這幾個緩衝io函式外,c標準庫裡面還提供了一系列封裝的io函式:如puts、putchar、printf等。

為什麼要有增加緩衝區這個功能呢?主要是因為io操作時,作業系統要從使用者態轉換為核心態的,而這個轉換過程相對來說比較慢,因此可以通過緩衝的形式減少轉換到核心態的次數。

那麼,緩衝io函式又是如何工作的呢?

那麼,我們該如何選擇哪一組i/o函式呢?

i/o函式也用於讀寫裝置,比如終端或網路裝置。此時通常需要更快的響應,一般不使用緩衝i/o函式。

ps:嚴格來講,就算是posix的i/o函式,仍然是有核心i/o緩衝的,所以write也不一定是直接寫到檔案的,也可能寫到核心i/o緩衝區中,至於究竟寫到了檔案中還是核心緩衝區中對於程序來說是沒有太大差別的,我們不用太關注這一點。

#include #include int main(void)

執行該函式時,read函式會一直阻塞到在螢幕上輸入資料並回車(此時stdin有資料可用)為止。

阻塞io有乙個很大的問題是:無法實現併發。當同時進行多個io操作的時候,前面的檔案資料不可用的時候(往往是socket之類的ipc操作),後面的io操作無法執行。

非阻塞io則可以很好的解決這個問題,要使用非阻塞io操作,需要在open的時候制定o_nonblock標誌。這樣,如果裝置暫時沒有資料可讀就返回-1,呼叫者應該試著再讀一次(again)。這種行為方式稱為輪詢(poll),呼叫者只是查詢一下,而不是阻塞在這裡死等,這樣可以同時監視多個裝置:

#include #include #include int main(void)

write(stdout_fileno, buf, n);

close(fd);

return 0;

}

ps:為了示例函式簡單,我這裡沒有考慮異常情況(如open失敗)的處理,而這些是在實際專案中是必不可少的。

非阻塞i/o有乙個缺點,如果所有裝置都一直沒有資料到達,呼叫者則需要反覆查詢,這樣會一直佔著cpu不放。因此,在使用非阻塞i/o時,通常不會在乙個while迴圈中一直不停地查詢(這稱為tight loop),而是每延遲等待一會兒來查詢一下,以免做太多無用功,在延遲等待的時候可以排程其它程序執行。

但是,這樣又引入了乙個新的問題,可能導致資料讀取的不夠及時,就拿我前面的例子來說,我在每次迴圈的時候sleep了一秒。如果剛開始sleep的時候資料可用,但此時卻無法立即響應,需要到sleep結束後鍾才能輸出結果。

要解圓滿解決這個問題,則需要用到select函式,它可以阻塞地同時監視多個裝置,還可以設定阻塞等待的超時時間,由於select多見於socket程式設計場景,這裡不大好舉例,後續如果會介紹socket程式設計的時候再詳細介紹它,要了解它的工作原理可以看一下這篇文章select,多路同步i/o模型。

來自為知筆記(wiz)

C 核心程式設計 05檔案操作

程式執行時產生的資料都屬於臨時資料,程式一旦執行結束都會被釋放 通過檔案可以將資料持久化 c 中對檔案操作需要包含標頭檔案 fstream 檔案型別分為兩種 文字檔案 檔案以文字的ascii碼形式儲存在計算機中 二進位制檔案 檔案以文字的二進位制形式儲存在計算機中,使用者一般不能直接讀懂它們 操作檔...

2019 10 15檔案的讀寫

開啟檔案的讀寫操作需要包含.為了讀而開啟檔案需要建立乙個ifstream物件,為了寫而開啟檔案,要建立乙個ofstream物件。檔案開啟了就可以像處理其他iostream物件一樣進行讀寫。將乙個檔案的內容拷貝到另乙個檔案 include include includeusing namespace ...

python 05 檔案操作

開啟檔案。引數 檔名,訪問模式 f open test.txt w 關閉檔案 f.close f open test.txt w 寫入資料 f.write hello world,i am here f.close 注意 f open test.txt r content f.read 5 prin...