C語言之I/O
檔案流的概念
概念:在C語言對檔案的操作最終轉化為對快取中的資料進行操作,流實際上就是記憶體中的一種具有自動順序操作的特殊資料,流如同流動的河水一樣,它具有源和目標地 。
按方向來分:以快取為中心:流入快取的是輸入,流出的是輸出流
1:輸入流:從檔案讀取的流
2:輸出流:將資料輸出到檔案的流
按流的資料內容:根據文字檔案和二進位制檔案來區分為檔案流和二進位制流
1:檔案流,文字流就是流動的字元序列
2:二進位制流:流動的二進位制序列
三個標準流:
1:標準輸入流 stdin(0):針對標準輸入鍵盤
2:標準輸出流stdout(1):針對標準輸出螢幕
3:標準錯誤流 stderr(2):針對標準輸出螢幕
檔案的概念
所謂“檔案”是指一組相關資料的有序集合,這個資料集合有一個名稱,叫做”檔案”,如:原始檔,目標檔案,可執行檔案,標頭檔案,二進位制檔案,.java,.o,等等一系列檔案
檔案一般都是駐留在外部介質(磁碟中),在使用的時候才去將檔案讀入到記憶體中來;
從使用者角度分類可以分為普通檔案和裝置檔案兩種;
從編碼方式來分類的話可以分為文字檔案和二進位制檔案兩種 。
檔案系統的分類
目前C語言所使用的磁碟檔案系統分為緩衝檔案系統和非緩衝的檔案系統
緩衝檔案系統 :系統會在記憶體區域開闢一個快取用來做為中繼儲存結構,先將檔案內容讀取到快取中去,然後再從快取中讀取,包括寫檔案也是一樣的,先到快取,再從快取到檔案。(快取的大小決定了讀檔案讀多少的最終臨界),快取的設定減少對磁碟的實際讀寫次數,從而來提高讀寫的效率
非緩衝檔案系統:系統不會提供一個快取,程式對直接對檔案進行操作(可以使用者自己來設定) ,在程式中我們可以自己根據需要去設定一些快取,來儲存讀寫的資料,儲存到自己快取中,然後從快取中再進行讀寫; 使用者在程式中為每個檔案讀寫設定一個緩衝區域 。
I/O函式
I/O函式以三種基本的形式處理資料:單個字元,文字行,二進位制資料。
- 只用於執行stdin 或stdout;
- 作為引數的流使用
- 使用記憶體中的字串而不是流。
開啟流
使用FILE *fopen(const char *path, const char *mode);函式來開啟檔案
//以輸入方式開啟文字/二進位制檔案,只讀。前提是檔案必須存在
fp =fopen( "txtFileName", "r" );
fp =fopen( "binFileName", "rb" );
//建立輸出方式文字/二進位制檔案,只寫。如存在此名字檔案,則清除原有內容
fp =fopen( "txtFileName", "w" );
fp =fopen( "binFileName", "wb" );
//以輸入輸出方式開啟文字/二進位制檔案,可讀可寫,指標指向檔案頭
fp =fopen( "txtFileName", "r+" );
fp =fopen( "binFileName", "rb+" );
//以輸入輸出方式開啟文字/二進位制檔案,可讀可寫,指標指向檔案尾
fp =fopen( "txtFileName", "a+" );
fp =fopen( "binFileName", "ab+" );
關閉流
使用 int fclose(FILE *fp);來關閉檔案
注意:不關閉檔案有可能會丟失資料,呼叫fclose之後,系統會重新整理快取,將快取區域中的資料全部重新整理到檔案中去。然後再去釋放檔案
字元I/O
getchar和putchar函式(標準輸入輸出)
getchar函式:
int getchar();
功能:從標準輸入讀取一個字元
返回:成功返回讀取的字元,失敗就會返回EOF
putchar函式
int putchar(int ch);
功能:將一個字元寫入到標準輸出
返回:成功返回寫入的字元ch,失敗返回EOF
fgetc和fputc函式(getc和putc函式)
fgetc函式:
int fgetc(FILE *f);
功能:從fp指向的檔案中讀取一個字元
返回:成功會返回讀取的字元,失敗或讀到檔案尾部返回EOF(-1);
可以對標準輸入進行操作;
fgetc(stdin);
fputc函式:
int fputc(int ch,FILE *fp);
功能:把一個字元ch寫如到fp指向的檔案中去,
返回:成功返回寫入的字元,失敗返回EOF
可以針對標準輸出:
fputc(int ch,stdout);
ungetc函式:
int ungetc(int c,FILE *fp);
功能:撤銷一個字元
返回:成功則返回撤銷的字元,失敗返回EOF
未格式化的行I/O
fgets和fputs函式
fgets函式:
char *fgets(char *str,int size,FILE *fp);
功能:從fp所指向的檔案中 最多讀size-1個字元,
放入str指向的字元陣列中,如果在讀入的size-1
個字元結束前遇到換行符或者EOF,讀入即結束,字串讀入後在最後一位加'\0'字元
返回:返回的就是str這個指標,失敗返回NULL,
同時也可以針對標準輸入:
與scanf相互對比的話,scanf在有空格的情況下是讀寫不了的
fputs函式
int fputs(char *str,FILE *fp);
功能:把str指向的字串或字元陣列寫入到fp指向的檔案中去,
返回:成功返回0,失敗則返回EOF
也可以針對標準輸入操作
gets和puts函式
gets函式
char *gets( char *str );
功能:從標準輸入裝置讀取字串,直到遇到換行或者EOF。換行符被認為是終止字元。
返回:若函式呼叫成功,返回字串;否則返回NULL。
puts函式
int puts( char *str );
功能:從標準輸出裝置寫出字串。
返回:若成功呼叫,返回非負值;否則EOF。
格式化的行I/O
fscanf和fprintf函式
fscanf函式
int fscanf(FILE *fp,const char *format...);
fprintf函式
int fprintf(FILE *fp ,const char *format...);
功能:按format的格式對fp指向的檔案進行I/O操作
返回:成功返回I/O位元組數,失敗或到檔案尾返回EOF
可以針對標準輸入和輸出進行操作;
scanf和printf函式
scanf函式
int scanf(const char *format, ...);
功能:格式輸入函式,即按使用者指定的格式從鍵盤上把資料輸入到指定的變數之中。
printf函式
int printf(const char *format, ...);
功能:格式化輸出函式, 一般用於向標準輸出裝置按規定格式輸出資訊
二進位制I/O
fread和fwirte函式
fread和fwite函式:
int fread(void *buffer,int num_bytes,int count ,FILE *fp);
int fwrite(void * buffer,int num_bytes,int count,FILE *fp);
功能:讀取資料塊,一般用於二進位制檔案的輸入和輸出
返回:成功返回讀寫的元素個數,失敗或到檔案尾部返回EOF
fread > 0 說明讀寫成功
引數:
buffer:一個指向要進行輸入輸出資料儲存區的通用指標
num_bytes:每個要讀寫的元素的位元組數目
count:要讀寫的元素個數
fp:要讀寫的檔案指標
補充:
1:對於二進位制檔案feof可以判斷是否讀到檔案結尾:
!feof(spIn) //判斷是否讀取到了檔案的結尾部分,但是是需要提前讀取一次的
size_t re = fread();
2:fread和fwrite在讀寫二進位制檔案的時候效率是更高的。
在記憶體和磁碟頻繁交換資料的情況下,儘量使用fread和fwrite函式
其他函式
fseek函式
int fseek(FILE * fp,long offset,int whence);
功能:使fp所指向的位置指標重置到指定位置(從whence位置移動offset個位元組)
返回:成功返回0,失敗返回EOF(-1)
offset:位移量,表示移動的位元組數(偏移量)
whence的值:
SEEK_SET 檔案首 0 offset非負
SEEK_CURRENT 檔案當前的位置 1 offset正負都可以
SEEK_END 檔案尾部 2 offset正負都是可以的
rewind函式
void rewind(FILE *fp);
功能:使檔案位置指標重新返回檔案首部
與fseek進行聯用,對檔案位置指標進行重置
remove函式
int remove(const char * filename);
功能:用於刪除指定的函式
fflush函式:
void fflush(FILE *fp);
功能:重新整理緩衝區域,如果開啟檔案進行讀操作,該函式將會清空檔案的輸入緩衝區,
如果開啟檔案進行讀寫操作時,該函式將檔案的輸出緩衝區內容寫入檔案中去;
ftell()函式
long int ftell(FILE *stream)
功能:在檔案末尾移動檔案指標後,我們可以使用ftell()函式獲取檔案的總大小。可以使用SEEK_END常量來將檔案指標移動檔案末尾。
返回:返回指定流的當前檔案指標的位置。