標準IO與檔案IO[領卓教育]
1.定義 標準IO:標準I/O是ANSI C建立的一個標準I/O模型,是一個標 準函式包和stdio.h頭中的定義,具有一定的可移植性。標準IO庫處理很多細節。例如快取分配,以優化長度執行IO等。標準的IO提供了三種類型的快取。 (1)全快取:當填滿標準IO快取後才進行實際的IO操作。 (2)行快取:當輸入或輸出中遇到新行符時,標準IO庫執行IO操作。 (3)不帶快取:stderr就是了。
檔案IO:檔案IO稱之為不帶快取的IO(unbuffered I/O)。不帶快取指的是每個read,write都呼叫核心中的一個系統呼叫。也就是一般所說的低階I/O——作業系統提供的基本IO服務,與os繫結,特定於unix平臺。 2.區別 首先:兩者一個顯著的不同點在於,標準I/O預設採用了緩衝機制,比如呼叫fopen函式,不僅開啟一個檔案,而且建立了一個緩衝區(讀寫模式下將建立兩個緩衝區),還建立了一個包含檔案和緩衝區相關資料的資料結構(FILE )。低階I/O一般沒有采用緩衝,需要自己建立緩衝區,不過其實在
2.fclose與close 與開啟檔案相對的,標準I/O使用fclose關閉檔案,將檔案指標傳入即可,如果成功關閉,返回0,否則返回EOF 比如: if(fclose(fp)!=0) printf(“Error in closing file”);
而*nix使用close用於關閉open開啟的檔案,與fclose類似,只不過當錯誤發生時返回的是-1,而不是EOF,成功關閉同樣是返回0。C語言用error code來進行錯誤處理的傳統做法。
3.讀檔案:getc,fscanf,fgets和read 標準I/O中進行檔案讀取可以使用getc,一個字元一個字元的讀取,也可以使用gets(讀取標準io讀入的)、fgets以字串單位進行讀取(讀到遇到的第一個換行字元的後面),gets(接受一個引數,檔案指標)不判斷目標陣列是否能夠容納讀入的字元,可能導致儲存溢位(不建議使用),而fgets使用三個引數char * fgets(char *s, int size, FILE *stream); 第一個引數和gets一樣,用於儲存輸入的地址,第二個引數為整數,表示輸入字串的最大長度,最後一個引數就是檔案指標,指向要讀取的檔案。最後是fscanf,與scanf類似,只不過增加了一個引數用於指定操作的檔案,比如fscanf(fp,"%s",words) *nix系統中使用read函式用於讀取open函式開啟的檔案,函式原型如下: ssize_t numread=read(int fd,void *buf,size_t qty);
其中fd就是open返回的檔案描述符,buf用於儲存資料的目的緩衝區,而qty指定要讀取的位元組數。如果成功讀取,就返回讀取的位元組數目(小於等於qty)。
4.判斷檔案結尾 如果嘗試讀取達到檔案結尾,標準IO的getc會返回特殊值EOF,而fgets碰到EOF會返回NULL,而對於*nix的read函式,情況有所不同。read讀取qty指定的位元組數,最終讀取的資料可能沒有你所要求的那麼多(qty),而當讀到結尾再要讀的話,read函式將返回0.
5.寫檔案:putc,fputs,fprintf和write 與讀檔案相對應的,標準C語言I/O使用putc寫入字元,比如:putc(ch,fp);第一個引數是字元,第二個是檔案指標。而fputs與此類似:fputs(buf,fp);僅僅是第一個引數換成了字串地址。而fprintf與printf類似,增加了一個引數用於指定寫入的檔案,比如:fprintf(stdout,“Hello %s.\n”,“dennis”);切記fscanf和fprintf將FILE指標作為第一個引數,而putc,fputs則是作為第二個引數。 在*nix系統中提供write函式用於寫入檔案,原型與read類似:ssize_t result=write(int fd,void *buf ,size_t amt);fd是檔案描述符,buf是將要寫入的記憶體資料,amt是要寫的位元組數。如果寫入成功返回寫入的位元組數,通過result與amt的比較可以判斷是否寫入正常,如果寫入失敗返回-1
6.隨機存取:fseek()、ftell()和lseek() 標準I/O使用fseek和ftell用於檔案的隨機存取,先看看fseek函式原型int fseek(FILE *stream, long offset, int whence);第一個引數是檔案指標,第二個引數是一個long型別的偏移量(offset),表示從起始點開始移動的距離。第三個引數就是用於指定起始點的模式,stdio.h指定了下列模式常量: SEEK_SET 檔案開始處 SEEK_CUR 當前位置 SEEK_END 檔案結尾處 看幾個呼叫例子: fseek(fp,0L,SEEK_SET); //找到檔案的開始處 fseek(fp,0L,SEEK_END); //定位到檔案結尾處 fseek(fp,2L,SEEK_CUR); //檔案當前位置向前移動2個位元組數 而ftell函式用於返回檔案的當前位置,返回型別是一個long型別,比如下面的呼叫: fseek(fp,0L,SEEK_END);//定位到結尾 long last=ftell(fp); //返回當前位置 那麼此時的last就是檔案指標fp指向的檔案的位元組數。 與標準I/O類似,*nix系統提供了lseek來完成fseek的功能,原型如下: off_t lseek(int fildes, off_t offset, int whence); fildes是檔案描述符,而offset也是偏移量,whence同樣是指定起始點模式,唯一的不同是lseek有返回值,如果成功就 返回指標變化前的位置,否則返回-1。whence的取值與fseek相同:SEEK_SET,SEEK_CUR,SEEK_END,但也可以用整數 0,1,2相應代替。
fseek和ftell == lseek;