C、C++一次將整個檔案讀入記憶體
阿新 • • 發佈:2019-01-22
@1.問題描述:
C和C++的初學者經常採用一行一行讀入檔案的辦法對檔案資料進行處理。但是經常會有一些情況需要將一個檔案整體一次讀入記憶體處理。而C和C++庫中並沒有提供直接一次讀入檔案全部資料的函式。
@2.解決方法:
目前給出C和C++的解決方案,下面兩個程式只是用於演示,不過這些程式碼已經很容易改寫成想要的函數了。
解決這個問題的思路是:
1.由於要將檔案完整讀入,所以必須使用二進位制方式開啟(若文字方式開啟,檔案流中會把一些非字元的資料過濾掉,我們將讀取不到那些內容)。
2.開啟檔案後,我們首先獲取檔案的大小,然後在記憶體中分配足夠的空間,再把檔案拷貝到記憶體空間中。之後使用記憶體空間進行資料處理,演示程式中沒有真正的處理,我們只是簡單將其輸出。
@3.程式碼:
C實現
- #include <stdio.h>
- #include <stdlib.h>
- int main ()
- {
- FILE * pFile;
- long lSize;
- char * buffer;
- size_t result;
- /* 若要一個byte不漏地讀入整個檔案,只能採用二進位制方式開啟 */
- pFile = fopen ("test.txt", "rb" );
- if (pFile==NULL)
- {
-
fputs ("File error"
- exit (1);
- }
- /* 獲取檔案大小 */
- fseek (pFile , 0 , SEEK_END);
- lSize = ftell (pFile);
- rewind (pFile);
- /* 分配記憶體儲存整個檔案 */
- buffer = (char*) malloc (sizeof(char)*lSize);
- if (buffer == NULL)
- {
- fputs ("Memory error",stderr);
-
exit (2);
- }
- /* 將檔案拷貝到buffer中 */
- result = fread (buffer,1,lSize,pFile);
- if (result != lSize)
- {
- fputs ("Reading error",stderr);
- exit (3);
- }
- /* 現在整個檔案已經在buffer中,可由標準輸出列印內容 */
- printf("%s", buffer);
- /* 結束演示,關閉檔案並釋放記憶體 */
- fclose (pFile);
- free (buffer);
- return 0;
- }
C++實現
- #include <iostream>
- #include <fstream>
- usingnamespace std;
- int main () {
- filebuf *pbuf;
- ifstream filestr;
- long size;
- char * buffer;
- // 要讀入整個檔案,必須採用二進位制開啟
- filestr.open ("test.txt", ios::binary);
- // 獲取filestr對應buffer物件的指標
- pbuf=filestr.rdbuf();
- // 呼叫buffer物件方法獲取檔案大小
- size=pbuf->pubseekoff (0,ios::end,ios::in);
- pbuf->pubseekpos (0,ios::in);
- // 分配記憶體空間
- buffer=newchar[size];
- // 獲取檔案內容
- pbuf->sgetn (buffer,size);
- filestr.close();
- // 輸出到標準輸出
- cout.write (buffer,size);
- delete []buffer;
- return 0;
- }
@4.注意的問題:
在這個演示程式中,如果採用文字方式開啟會如何呢?即把C實現中的檔案開啟改為pFile = fopen ("test.txt","r" ),C++中的檔案開啟改為filestr.open ("test.txt")
雖然這個用於測試的檔案本身是一個文字檔案,文字內容為:
test.txt
- abcdefghijklm
- abcdefghijklm
- ppdsbd
但是如果採用文字模式開啟仍會出現問題,測試中的“C實現”程式碼的程式會輸出:
- Reading error
原因是有一些字元被檔案流處理掉了,這造成fread函式講到的字元數少於檔案大小lSize,返回值result不等於lSize於是程式輸出Reading error後退出了。
同樣的情況在C++實現的程式碼中也有,但是C++程式並沒有退出,但它的輸出結果不對,內容如下(僅為本機測試結果,因時因機器而異)
- abcdefghijklm
- abcdefghijklm
- ppdsbdes\M