5 2 流與FILE物件

2021-06-19 01:32:25 字數 2488 閱讀 2926

open、lseek、read、write和close等函式在標準i/o庫中都有對應的函式。為什麼還要建立這些看似重複的標準i/o庫?原因有二:

一、標準庫屬於c標準內容之一,不專屬於某個作業系統。有了標準i/o庫,c語言就具有更好的可移植性。

二、標準庫提供了更多標準的i/o操作,使得i/o操作更加便利和簡單。

使用read和write讀寫檔案時,一般要經過這麼個過程:

1、定義乙個檔案描述符變數作為操作物件。例如:

int filedes;

2、定義乙個陣列作為操作空間,所謂的緩衝區。例如:

char buf[bufsiz];

3、使用open開啟檔案獲得乙個檔案描述符。例如:

filedes = open(pathname, o_rdwr | o_creat);

4、用read從指定的檔案描述符所代表的檔案上把資料讀到指定的緩衝區。例如:

read(filedes, &buf,bufsiz);

5、或者用write從指定的緩衝區把資料寫入指定的檔案描述符所代表的檔案裡。例如:

write(filedes, &buf, bufsiz);

6、使用close關閉檔案。例如:

close(fieldes);

這個過程有這麼幾個特點(也可以看作是乙個缺點):

1、任何乙個函式都不會自動給你分配空間,必須自己提供空間buf。

2、要合理的規劃空間大小bufsiz,這個涉及i/o效率的問題。

3、read和write是直接把資料送往核心的,每呼叫一次就會產生一次系統呼叫,系統呼叫的代價是很高很高的,需要通過一些機制先把要寫入核心的資料先存到一些變數中,然後在適當的時候在一次呼叫write寫進去,或呼叫read一次性讀出來。

4、當要向顯示器顯示資料時,我們需要做很多轉換工作。例如要顯示整數65。下面**絕對不是我們所期待的「65」這兩個字元,而是顯示乙個大寫字母「a」。

int mynumber = 65;

write(stdout_fileno, &mynumber, 1);

更不能這麼寫:

write(stdout_fileno, 65, 1);
要呼叫write輸出乙個整數65。我們先要構造10個數值(1,2,3,4,5,6,7,8,9,0)和10個字元('1','2','3','4','5','6','7','8','9','0')的ascii值對應表,還要把「6」和「5」逐位「拆」下來。如果只是寫乙個函式顯示乙個整數變數,可能還沒那麼複雜。要是寫乙個通用函式,既要顯示整數、小數、整數、負數、字元、陣列,還要考慮是十進位制還是十六進製制格式,那就非常繁雜了。

標準i/o庫函式就是解決這些問題而提出的。其中:

(1)流:解決上述問題1和問題2,即空間分配問題。

(2)緩衝:解決上述問題3,即i/o效率問題。

(3)格式化輸出函式fprintf等解決上述問題4,輸入和輸出轉換問題。

很多書把「流」這個概念解釋得像魔鬼那樣的抽象而難以琢磨。其實可以這麼理解:流是乙個file型別的資料物件。file是乙個struct型別的資料型別。大致模樣是這樣:

typedef struct

file;

也就是把前面的分散定義的檔案描述符和緩衝區等定義「整合」到乙個file結構中。這樣,我們就可以構造一系列針對file結構進行操作的函式,其中包括對file物件初始化等等。

所以說file是流的資料型別,而流是file型別的資料物件。所有標準i/o都是針對流物件展開的。其中:

(1)fopen函式建立了乙個流物件,並返回該物件的指標。相當於open函式,不過open函式返回的是檔案描述符。fopen函式內部自動建立了乙個buffer緩衝區和檔案描述符,並自動選擇了乙個合適的bsize。

(2)fwrite函式向流寫入資料,資料實際上是把資料寫到file物件中的buffer緩衝區,而非系統核心的緩衝區。除非緩衝區已經滿了(即file物件中curp=buffer+bsize)。如果緩衝區滿了,函式內部會自動呼叫read函式把資料寫到核心。

(3)fread函式是從流物件中取出資料,實際上是從file物件的buffer緩衝區取得資料,而非直接從核心的緩衝區取得資料。除非緩衝區已經沒有資料可以取了(即file物件中curp=buffer)。如果緩衝區空了,函式內部會自動呼叫write函式一次性取出很多資料,直到把緩衝區填滿。

(4)如果不需要等到緩衝區填滿,而是要馬上寫到核心,就呼叫沖洗函式fflush,強制把資料寫到核心並清空緩衝區。當然了,寫到核心的資料也未必就馬上寫到磁碟上,核心也有緩衝,甚至一直到磁碟的過程還有很多級緩衝,例如dma緩衝,還有磁碟裝置本身也有緩衝機制。

一句話:流是乙個初始化了的file物件。而檔案指標是file物件的指標。

IO流中File物件常用方法

記錄一下學習之路之io流 file物件常用方法有 boolean canread 接受檔名作為字串 boolean canwrite 檢查能否寫入指定檔案 boolean equals object obj 將指定物件與呼叫函式的物件進行比較 boolean exists 測試檔案是否存在 stri...

總結 File與IO流初學

寫入檔案 public static void main string args throws exception f2.close system.out.println 讀取成功 建立檔案 file file new file d test string partent file.getparen...

標準I O流和FILE物件常用函式

fife 指標 有關於檔案的資訊結構體。一 緩衝檔案系統分類 1.全快取 開啟乙個檔案是全緩衝。2.行快取 當流遇到乙個終端的時候,是乙個典型的行快取。當輸入,輸出遇到新行符,進行i o操作。3.不快取 不對字元進行緩衝,例如 stderr 人機互動,標準出錯。使用setbuf setvbuf 可以...