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 返回成功輸入的數據項的個數。若返回值小於函數調用中的第三個實參,則說明發生了一個讀錯誤

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章