天天看點

fread函數以二進制模式和文本模式打開的差別

檔案1.txt中的内容如下:

  “456”
用下面的方式統計檔案的位元組數:   
  
   fseek(fp, 0, SEEK_END);
     file_len = ftell(fp);則file_len統計了檔案1.txt中的位元組數為:8
用函數 readLen = fread(data, 1, num, fp);讀取到的位元組數為:7

為什麼兩者會不一樣呢?

函數聲明:int fread( void *buffer, size_t size, size_t num, FILE *stream );

 說明:函數fread()讀取[num]個對象(每個對象大小為size(大小)指定的位元組數),并把它們替換到由buffer(緩沖區)指定的數組。資料來自給出的輸入流,函數的傳回值是讀取的内容數量。

 如果此時,需要讀一個1024位元組的文本,那麼可以設定size為1,num為1024。當然,可以是size為1024,num為1。

 問題也就來了,這兩種方式哪個好呢。。。我習慣的是前者,這樣的話fread的傳回值為讀入的位元組數。及時讀入有問題,也比較容易發現。而如果是後者,那麼當fread沒有讀入預想到的長度(比如size = 1024)那麼fread的傳回值會是0這就比較麻煩了。。。

 這還有問題可能更有意思,一開始還真沒怎麼注意到,先看一段MSDN:

 If the given stream is opened in text mode, carriage return–linefeed pairs are replaced with single linefeed characters. The replacement has no effect on the file pointer or the return value.

就是說如果按“文本模式”打開一個檔案,那麼在讀入的時候,Windows預設的換行符CR+LF就會轉換成一個單個的LF。

 那麼也就是說,如果一個文本檔案的大小為1024位元組,一共100行,那麼fread最多隻能讀入924個位元組。

 在這種情況下,fread( buffer, 1, 1024, stream )的傳回值将會是924個位元組。
 fread( buffer, 1024, 1, stream )的傳回值,将會是0

這也就解釋了開始為什麼兩者統計的結果會不一樣。當我們把開始的改成下面形式:(即以二進制模式打開檔案)

用下面的方式統計檔案的位元組數:   
   fp = fopen("1.txt", "rb");
   fseek(fp, 0, SEEK_END);
     file_len = ftell(fp);則file_len統計了檔案1.txt中的位元組數為:8
用函數 readLen = fread(data, 1, num, fp);讀取到的位元組數為:8

這也兩者的結果就一樣了。