檔案讀寫IO

weixin_34054866發表於2013-09-25

摘要:本文主要總結了以下有關檔案讀寫的IO,系統呼叫與庫函式。


1.初級IO函式:close,creat,lseek,open,write


檔案描述符是一個整型數


1.1close


1.2int creat(const char * pathname, mode_t mode);

 

int creat(const char * pathname, mode_t mode);
函式功能:
建立一個檔案並以只寫的方式開啟。如果原來該檔案存在,會將這個檔案的長度截短為0。
函式說明
若函式執行成功則返回開啟檔案的描述符,出錯返回-1並設定errno。(關於errno詳見《UNIX環境高階程式設計》第一章第七節)
引數pathname指向欲建立的檔案路徑字串。creat()相當於使用下列的呼叫方式呼叫open()
open(const char * pathname ,(O_CREAT|O_WRONLY|O_TRUNC));
由於creat函式建立檔案後是以只寫的方式開啟,因此侷限性比較大,所以一般都用open函式來代替creat函式建立一個檔案,這樣建立後就能同時以讀寫的方式開啟檔案了。


 

1.3off_t lseek(int fildes,off_t offset ,int whence)

 

#include<sys/types.h>
#include<unistd.h>

定義函式

off_t lseek(int fildes,off_t offset ,int whence);

函式說明

每一個已開啟的檔案都有一個讀寫位置,當開啟檔案時通常其讀寫位置是指向檔案開頭,若是以附加的方式開啟檔案(如O_APPEND),則讀寫位置會指向檔案尾。當read()或write()時,讀寫位置會隨之增加,lseek()便是用來控制該檔案的讀寫位置。引數fildes 為已開啟的檔案描述詞,引數offset 為根據引數whence來移動讀寫位置的位移數。
Offset:偏移量,每一讀寫操作所需要移動的距離,單位是位元組的數量,可正可負(向前移,向後移)。

引數

whence為下列其中一種:(SEEK_SET,SEEK_CUR和SEEK_END和依次為0,1和2).
SEEK_SET 將讀寫位置指向檔案頭後再增加offset個位移量。
SEEK_CUR 以目前的讀寫位置往後增加offset個位移量。
SEEK_END 將讀寫位置指向檔案尾後再增加offset個位移量。
當whence 值為SEEK_CUR 或SEEK_END時,引數offet允許負值的出現。
下列是較特別的使用方式:
1) 欲將讀寫位置移到檔案開頭時:
lseek(int fildes,0,SEEK_SET);
2) 欲將讀寫位置移到檔案尾時:
lseek(int fildes,0,SEEK_END);
3) 想要取得目前檔案位置時:
lseek(int fildes,0,SEEK_CUR);

返回值

當呼叫成功時則返回目前的讀寫位置,也就是距離檔案開頭多少個位元組。若有錯誤則返回-1,errno 會存放錯誤程式碼

1.4int open(const char *pathname, int flags);

 

作用:開啟和建立檔案。
簡述:
#include <fcntl.h>

intopen(const char *pathname, int flags, mode_t mode);
返回值:成功則返回檔案描述符,否則返回 -1
對於open函式來說,第三個引數僅當建立新檔案時(即 使用了O_CREAT 時)才使用,用於指定檔案的訪問許可權位(access permission bits)。pathname 是待開啟/建立檔案的POSIX路徑名(如/home/user/a.cpp);flags 用於指定檔案的開啟/建立模式,這個引數可由以下常量(定義於fcntl.h)通過邏輯位或邏輯構成。
O_RDONLY 只讀模式
O_WRONLY 只寫模式
O_RDWR 讀寫模式

 

1.5ssize_t write (int fd,const void * buf,size_t count);

返回值:如果順利write()會返回實際寫入的位元組數。當有錯誤發生時則返回-1,錯誤程式碼存入errno中。

        0)非緩衝檔案系統依賴於作業系統,通過作業系統的功能對檔案進行讀寫,是系統級的輸入輸出,它不設檔案結構體指標,只能讀寫二進位制檔案,但效率高、速度 快,由於ANSI標準不再包括非緩衝檔案系統,因此建議大家最好不要選擇它。

 

1)關於系統呼叫

read和write屬於初級讀寫函式,也是系統呼叫;系統呼叫需要消耗大量時間。因為程式碼執行權會從使用者轉移到核心,執行核心程式碼是需要時間的。系統呼叫開銷巨大,因為系統呼叫需要特殊的記憶體和堆疊環境,這些需要在系統呼叫之前建立好;系統呼叫之後又需要恢復這些環境。這種環境切換需要耗費大量時間。最好的方法就是建立緩衝區,一次讀取大量資料,避免多次進行系統呼叫。我們可以用這個思想來改造前一篇中的who。

2)系統呼叫的錯誤處理

一般約定,系統呼叫open,write,lseek在出錯時會返回值-1。另外,系統呼叫都有自己的錯誤集,以open為例,開啟檔案不存在,沒有讀的許可權,開啟檔案太多等等。核心通過全域性變數errno來確定錯誤型別,其中哦功能error.h中規定了一些錯誤的巨集。


2.標準IO函式


2.1int fclose(FILE *stream);

如果流成功關閉,fclose 返回 0,否則返回EOF(-1)


2.2int feof(FILE *stream)

feof(fp)有兩個返回值:如果遇到檔案結束,函式feof(fp)的值為非零值,否則為0。


2.3int fgetc(FILE *stream);

這個函式的返回值,是返回所讀取的一個位元組。如果讀到檔案末尾或者讀取出錯時返回EOF。


2.4char *fgets(char *buf, int bufsize, FILE *stream)

fopen從檔案結構體指標stream中讀取資料,每次讀取一行。讀取的資料儲存在buf指向的字元陣列中,每次最多讀取bufsize-1個字元(第bufsize個字元賦'\0'),如果檔案中的該行,不足bufsize個字元,則讀完該行就結束。函式成功將返回buf,失敗或讀到檔案結尾返回NULL。因此我們不能直接通過fgets的返回值來判斷函式是否是出錯而終止的,應該藉助feof函式或者ferror函式來判斷。bufsize的作用是防止緩衝區溢位。


2.5FILE * fopen(const char * path,const char * mode);

檔案順利開啟後,指向該流的檔案指標就會被返回。如果檔案開啟失敗則返回NULL,並把錯誤程式碼存在errno 中。

 

r 以只讀方式開啟檔案,該檔案必須存在。
r+ 以可讀寫方式開啟檔案,該檔案必須存在。
rb+ 讀寫開啟一個二進位制檔案,允許讀寫資料
rw+ 讀寫開啟一個文字檔案,允許讀和寫。
w 開啟只寫檔案,若檔案存在則檔案長度清為0,即該檔案內容會消失。若檔案不存在則建立該檔案。
w+ 開啟可讀寫檔案,若檔案存在則檔案長度清為零,即該檔案內容會消失。若檔案不存在則建立該檔案。


 

2.6int fputc (int n, File *fp)

功能:輸出一個字元到某個檔案

2.7size_t fread ( void   *buffer,  size_t size,  size_t count,  FILE *stream) ;

 

size
單個元素的大小,單位是位元組
返回值:

 

 

實際讀取的元素個數.如果返回值與count不相同,則可能檔案結尾或發生錯誤.
從ferror和feof獲取錯誤資訊或檢測是否到達檔案結尾.

 

2.8int fseek(FILE *stream, long offset, int fromwhere);

 

函式設定檔案指標stream的位置。如果執行成功,stream將指向以fromwhere(偏移起始位置:檔案頭0(SEEK_SET),當前位置1(SEEK_CUR),檔案尾2(SEEK_END))為基準,偏移offset(指標偏移量)個位元組的位置。如果執行失敗(比如offset超過檔案自身大小),則不改變stream指向的位置。
fseek函式和lseek函式類似,但lseek返回的是一個off_t數值,而fseek返回的是一個整型。


 

2.9size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream)

 

返回實際寫入的資料項個數count。
說明:寫入到檔案的哪裡? 這個與檔案的開啟模式有關,如果是w+,則是從file pointer指向的地址開始寫,替換掉之後的內容,檔案的長度可以不變,stream的位置移動count個數;如果是a+,則從檔案的末尾開始新增,檔案長度加大。

 

2.10int getc(FILE *stream);

注意: 此函式被ISO C宣告為一個巨集,所以在用時不能將其做為函式指標傳(有一些編譯器將其以函式形式也給另說)。


2.11getchar()

從stdio流中讀字元,相當於getc(stdin),它從標準輸入裡讀取下一個字元


2.12gets

從stdin流中讀取字串,直至接受到換行符或EOF時停止,並將讀取的結果存放在buffer指標所指向的字元陣列中。換行符不作為讀取串的內容,讀取的換行符被轉換為null值,並由此來結束字串。


2.13int fputc(char ch,FILE*fp)

putc()與fputc()等價。不同之處為:當putc函式被定義為巨集時,它可能多次計算stream的值。


2.14 int putchar(int ch);

在標準輸出上輸出一個字元


2.15int puts(char *string);

功能:送一字串到流stdout中

      緩衝檔案系統的特點是:在記憶體開闢一個“緩衝區”,為程式中的每一個檔案使用,當執行讀檔案的操作時,從磁碟檔案將資料先讀入記憶體“緩衝區”, 裝滿後再從記憶體“緩衝區”依此讀入接收的變數。執行寫檔案的操作時,先將資料寫入記憶體“緩衝區”,待記憶體“緩衝區”裝滿後再寫入檔案。由此可以看出,記憶體 “緩衝區”的大小,影響著實際操作外存的次數,記憶體“緩衝區”越大,則操作外存的次數就少,執行速度就快、效率高。一般來說,檔案“緩衝區”的大小隨機器 而定。


3.格式化輸出輸出函式


3.1printf


3.2int fprintf(FILE *stream,char *format,[argument])

功能:格式化輸出到一個流/檔案中;

返回值:fprintf()的返回值是輸出的字元數,發生錯誤時返回一個負值.


3.3scanf


3.4int fscanf(FILE *stream, char *format,[argument...]);

功 能: 從一個流中執行格式化輸入,fscanf遇到空格和換行時結束,注意空格時也結束。這與fgets有區別,fgets遇到空格不結束。


 

相關文章