天天看點

C語言 ——檔案處理(奇葩知識系列 )

1 引言

● 檔案是用來永久地儲存大批量資料的

● 計算機将檔案存儲在硬碟、固态盤、閃存盤和DVD盤這樣的輔存上

2 檔案與流

● 在C語言中,檔案不過是一個按順序組成的位元組流。當一個檔案被打開時,就會有一個流與這個檔案聯系在一起

● 當程式開始執行時有三個檔案及其相聯系的的流被自動打開——即标準輸入、标準輸出和标準錯誤

● 流提供了檔案與程式之間的資訊交流通道

● 标準輸入流使得程式能夠從鍵盤上讀入資料而标準輸出流使得程式能夠将資料列印到螢幕上

● 每次打開一個檔案都會傳回一個指向FILE結構體類型(在頭檔案<stdio.h>中定義)的指針,FILE結構體類型中包含有處理這個檔案有關的資訊。這個結構體中包含有一個檔案描述頭,檔案描述頭就是針對所謂"打開檔案清單"的一個作業系統數組的一個索引,數組的每一個元素包含有一個檔案控制塊(FCB),而作業系統就是通過FCB來管理一個特定的檔案的

● 系統通過檔案指針stdin,stdout和stderr來操縱标準輸入、标準輸出和标準錯誤這三個檔案

● 函數fgetc從一個檔案中讀取一個字元。它接收一個指向目标檔案的FILE指針作為實參

● 函數fputc向一個檔案中寫入一個字元。它接收一個欲寫入該目标檔案的字元和一個指向目标檔案的檔案指針作為實參

● 函數fgets和fputs分别用來從檔案中讀取一行和向檔案中寫入一行字元

3 順序存取檔案的建立

● C語言沒有将結構體運用在檔案之上。必須提供一個檔案結構來滿足某些應用的需求

● C程式用一個單獨的FILE結構體來管理每個檔案

● 每次打開一個檔案,都需要一個單獨聲明的、類型為FILE的指針,用于實作對檔案的引用

● 函數fopen需要兩個實參:檔案名和檔案打開模式,函數的傳回值是指向被打開檔案的FILE結構體類型的指針

● 檔案打開模式 w 表示檔案是為寫操作而打開的。若檔案事先并不存在,則函數fopen建立該檔案。若檔案事先存在,則檔案中原有的内容将會在不給出任何警告的情況下被全部丢棄

● 若無法打開一個檔案,則函數fopen傳回一個NULL值

● 函數feof接收一個指向FILE的指針。若檔案結束标記已經被設定,則函數傳回一個非零值(真),否則傳回0

● 函數fprintf基本上是等價于函數printf的,隻不過fprintf函數需要多接收一個檔案指針作為實參,這個檔案指針指向的檔案就是資料将要被寫入的目标檔案

● 函數fclose接收一個檔案指針作為實參并關閉該檔案

● 當一個檔案被打開時,它的檔案控制塊(FCB)就被複制到記憶體中。作業系統使用FCB來管理檔案

● 若想建立一個新檔案,或者想在寫入新的資料之前丢棄一個已有檔案中的全部内容則應該以寫(“w”)模式來打開一個檔案

● 若想讀取一個已存在的檔案,則應該以讀(“r”)模式來打開該檔案

● 若想在一個已存在的檔案末尾添加記錄,則應該以添加(“a”)模式來打開該檔案

● 若想對檔案既讀又寫,則可使用更新模式(“r +”,“w +”,“a +”)這三個中的一個來打開檔案。

  1. 模式 r + :為了 讀/寫 而打開一個檔案
  2. 模式 w + :為了 讀/寫 而建立一個檔案,若檔案已經存在那麼以這種方式打開檔案時,檔案中目前的内容都會被丢棄。
  3. 模式 a + :為了 讀/寫 而打開一個檔案但是所有的寫操作必須在檔案的末尾進行,若檔案事先并不存在則建立該檔案

    ● 每一個檔案打開模式都有一個與其相對應的二進制模式(加上字母 b),這些模式都是用來處理二進制檔案的

    ● C11還通過在模式 w,w+,wb,wb+的後邊增加一個 x ,來提供互斥寫模式

4 從順序檔案中讀取資料

● 函數fscanf基本上是等價于函數scanf的,隻不過fscanf函數需要多接收一個檔案指針作為實參,這個檔案指針指向的檔案就是要從中讀取資料的目标檔案

● 為了從順序存取檔案中提取特定的資料,程式要從檔案頭開始連續地讀取資料,直到發現欲提取的資料為止

● 函數rewind将程式的檔案位置指針重新定位于其實參所指向的檔案的開頭(即位元組編号為0)

● 檔案位置指針是一個整數值,這個整數值表示檔案中下一個 讀/寫 操作将發生在哪個位元組位置上。檔案位置指針也稱為檔案偏移量。檔案位置指針是與每個檔案相聯系的FILE結構體中的一個成員

● 順序檔案中的資料在被修改時,會具有破壞檔案中其他資料的風險

5 随機存取檔案

● 随機存取檔案中的記錄一般是固定長度的,無須搜尋其他記錄,就能夠直接通路這些記錄(是以速度快)

● 由于随機存取檔案中每一個記錄的長度都是相同的,是以,每一個記錄相對于檔案開頭的精确位置都可以根據基于記錄鍵的線性函數計算出來

● 固定長度的記錄,允許向一個随機存取檔案中插入資料,而不會破壞其他資料。還可以對已經存入檔案的資料進行更改或者删除,而無須重寫整個檔案

6 随機存取檔案的建立

● 函數fwrite将從某個特定位址開始存儲特定數目的位元組資料,從記憶體中轉移到一個檔案中,而檔案位置指針訓示了檔案中這些位元組資料被寫入的起始位址

● 函數fread将檔案位置指針訓示的位址開始存儲的特定數目的位元組資料,從一個檔案中轉移到某個特定位址開始的一個記憶體區域中

● 函數 fwrite 和 fread 具有将資料數組讀出或寫入檔案的功能。函數中的第三個實參表示要處理的元素個數

● 檔案處理程式通常都是一次寫一個結構體

● 函數 fwrite 每次都是向檔案中寫入一個資料塊(特定數目的位元組)

● 為了向磁盤檔案中寫入某個數組中的若幹個元素,在函數fwrite 調用語句中,需要将指向該數組的指針作為函數的第一個實參,将欲寫入的元素的個數作為第三個實參

7 随機地向一個随機存取檔案中寫入資料

● 函數 fseek 将檔案位置指針定位在檔案中某個特定位置上。其中,第二個實參表示檔案位置指針将要搜尋經過的位元組數,第三個實參表示檔案位置指針開始搜尋的位置。第三個實參有三個可選值:SEEK_SET 、SEEK_CUR 、SEEK_END (都在<stdio.h>中定義)

  1. SEEK_SET:表示搜尋從檔案的頭部開始
  2. SEEK_CUR:表示搜尋從檔案的目前位置開始
  3. SEEK_END:表示偏移量從檔案尾部開始計算

    ● 工業級應用程式應通過檢查函數的傳回值來判斷諸如 fscanf ,fseek ,fwrite 這樣的函數是否正确地執行了

    ● 函數 fscanf 傳回成功讀取的資料項的個數,若在讀的過程中發生了問題,也傳回EOF

    ● 當搜尋操作無法進行時,函數fseek将傳回一個非零值

    ● 函數fwrite 傳回成功輸出的資料項的個數。若傳回值小于函數調用中的第三個實參,則說明發生了一個寫錯誤

8 從一個随機存取檔案中讀取資料

● 函數 fread 将特定數目的位元組從一個檔案中讀入記憶體

● 通過提供指向一個存儲将要讀來的資料的數組的指針以及欲讀取元素的個數,fread 函數可以為該數組讀取若幹個固定長度的數組元素

● 函數 fread 傳回成功輸入的資料項的個數。若傳回值小于函數調用中的第三個實參,則說明發生了一個讀錯誤

繼續閱讀