C語言標準輸入輸出緩衝區

2021-10-04 21:24:03 字數 3232 閱讀 6971

緩衝區特徵

緩衝例項

file結構定義

參考資料

緩衝區又稱為快取,它是記憶體空間的一部分。也就是說,在記憶體空間中預留了一定的儲存空間,這些儲存空間用來緩衝輸入或輸出的資料,這部分預留的空間就叫做緩衝區。

緩衝區根據其對應的是輸入裝置還是輸出裝置,分為輸入緩衝區和輸出緩衝區。

為什麼要引入緩衝區

比如我們從磁碟裡取資訊,我們先把讀出的資料放在緩衝區,計算機再直接從緩衝區中取資料,等緩衝區的資料取完後再去磁碟中讀取,這樣就可以減少磁碟的讀寫次數,再加上計算機對緩衝區的操作大大快於對磁碟的操作,故應用緩衝區可大大提高計算機的執行速度。

又比如,我們使用印表機列印文件,由於印表機的列印速度相對較慢,我們先把文件輸出到印表機相應的緩衝區,印表機再自行逐步列印,這時我們的cpu可以處理別的事情。

現在您基本明白了吧,緩衝區就是一塊記憶體區,它用在輸入輸出裝置和cpu之間,用來快取資料。它使得低速的輸入輸出裝置和高速的cpu能夠協調工作,避免低速的輸入輸出裝置占用cpu,解放出cpu,使其能夠高效率工作。

緩衝區 分為三種型別:全緩衝、行緩衝和不帶緩衝。

在這種情況下,當填滿標準i/o快取後才進行實際i/o操作。全緩衝的典型代表是對磁碟檔案的讀寫。

一般磁碟檔案是全緩衝的(緩衝區一般為4096個位元組)。

在這種情況下,當在輸入和輸出中遇到換行符時,執行真正的i/o操作。這時,我們輸入的字元先存放在緩衝區,等按下回車鍵換行時才進行實際的i/o操作。典型代表是標準輸入(stdin)和標準輸出(stdout)。

注意:換行符也被讀入緩衝區。(緩衝區一般為1024個位元組)

也就是不進行緩衝,標準出錯情況stderr是典型代表,這使得出錯資訊可以直接盡快地顯示出來。

ansi c( c89 )要求快取具有下列特徵:

當且僅當標準輸入和標準輸出並不涉及互動裝置時,它們才是全快取的。

標準出錯決不會是全快取的。

但是,這並沒有告訴我們如果標準輸入和輸出涉及互動作用裝置時,它們是不帶快取的還是行快取的,以及標準輸出是不帶快取的,還是行快取的。

大部分系統預設使用下列型別的快取:

標準出錯是不帶快取的。

如果是涉及終端裝置的流,則它們是行快取的;否則是全快取的。

我們經常要用到標準輸入輸出流,而ansi c對stdin、stdout和stderr的快取特徵沒有強行的規定,以至於不同的系統可能有不同的stdin、stdout和stderr的快取特徵。目前主要的快取特徵是:stdin和stdout是行快取;而stderr是無快取的。

如果我們沒有自己設定緩衝區的話,系統會預設為標準輸入輸出設定乙個緩衝區,這個緩衝區的大小通常是4096個位元組的大小,這和計算機中的分頁機制有關,因為程序在計算機中分配記憶體使用的就是分頁與分段的機制,並且每個頁的大小是4096個位元組,因此通常情況下緩衝區的大小會設定為4096個位元組的大小。

緩衝區大小由stdio.h標頭檔案中的巨集bufsiz定義,如果希望檢視它的大小,包含標頭檔案,直接輸出它的值即可。

#include

intmain()

緩衝區的大小是可以改變的,也可以將檔案關聯到自定義的緩衝區,詳情可以檢視setbug()和setvbuf()函式。

下列情況會引發緩衝區的重新整理:

緩衝區滿時;

行緩衝區遇到回車時;

關閉檔案;

使用特定函式重新整理緩衝區,如fflush()函式

我們上面提到標準輸入輸出是行緩衝,即一行滿了才會重新整理,那什麼是重新整理呢?重新整理就是將資料從緩衝區取出來,真正能重新整理,要滿足什麼條件呢?

1、滿重新整理,即一行滿了(1024個位元組)才會重新整理;

2、遇到』\n』會重新整理;

3、呼叫fflush()函式;

4、程式結束 fclose();

//這是乙個分別列印三個標準流和乙個檔案流的緩衝方式的應用例項

#include

#include

#if defined(macos)

#define _io_unbuffered __snbf

#define _io_line_buf __slbf

#define _io_file_flags _flags

#define buffersz(fp) (fp)->_bf._size

#else

#define buffersz(fp) ((fp)->_io_buf_end - (fp)->_io_buf_base)

#endif

//以上是關於緩衝方式和緩衝區大小的預定義

void

pr_stdio

(const

char

*, file *);

//子函式宣告

intmain

(int argc,

char

*ar**)

//測試緩衝輸出函式

void

pr_stdio

(const

char

*name, file *fp)

else

if(fp->_io_file_flags & _io_line_buf)

else

printf

(", 緩衝區大小 = %ld\n"

,buffersz

(fp));

return

;}

我們以printf函式和stderr為例,先說明stdout(對應printf)是遇到換行符或緩衝區滿之後或程式結束後才輸出緩衝,stderr一般是無緩衝的:

/*

** 在我的實驗環境中,緩衝區大小預設為1024

*/#include

intmain()

return0;

}

執行結果:

(你可以數數,有1024個1,然後1024個』.』,…)

或者你可以通過用./a.out > t 2>&1重定向標準輸出和錯誤到檔案t中,這樣就可以很容易看到執行結果(因為程式跑的很快,很難找到開始執行出來的那一行),這時的緩衝區大小是4096個位元組。

標頭檔案

defines __file, _fpos_t.
預設定義

struct __sfile 

;

Redis 輸入輸出緩衝區

id 客戶端連線的唯一標識,這個id是隨著redis的連線自增的,重啟redis後會重置為0 addr 客戶端連線的ip和埠 fd socket的檔案描述符,與lsof命令結果中的fd是同乙個,如果fd 1代表當前客戶端不是外部客戶端,而是redis內部的偽裝客戶端。name 客戶端的名字,後面的c...

c語言輸入輸出緩衝區的概念

輸入輸出緩衝區的概念 我想以乙個例子說明,比如我想把一篇文章以字串行的方式輸出到計算機顯示器螢幕上,那麼我的程式記憶體作為資料來源而顯示器驅動程式作為資料目標,如果資料來源直接對資料目標傳送資料的話。資料目標獲得第乙個字元,便將它顯示。然後從埠讀取下乙個字元,可是這時就不能保證資料來源向埠傳送的恰好...

輸入緩衝區與輸出緩衝區

本博文通過一段程式來理解輸入緩衝區與輸出緩衝區。程式如下 author wanghao created time thu 17 may 2018 06 03 12 ampdt file name test.c description include int main int argc,const c...