C++ 檔案流處理
阿新 • • 發佈:2019-01-22
包含於#include<stdio.h> 的FILE 類:fread和feof
// 讀取檔案塊資料
size_t fread(void *buffer, size_t size, size_t count, FILE *file);
fread引數說明:buffer是讀取資料後存放地址,size是的塊長度,count是塊的數量,實際讀取長度為size*count,返回值為塊成功讀取塊的count數量。
//判斷上次讀操作是否遇到檔案末尾
int feof(FILE *stream);
feof返回0表示檔案沒有結束,返回1,表示結束。
feof實際觀察的是上次讀操作的內容,也就是上次讀操作fread返回的值,如果讀操作的返回值表明讀取的不是空,那feof就返回0,如果上次讀操作失敗了,則feof返回1,表示讀取完了。
在VC裡,只有當檔案位置指標(fp->_ptr)到了檔案末尾,然後再發生讀/寫操作時,標誌位(fp->_flag)才會被置為含有_IOEOF。然後再呼叫feof(),才會得到檔案結束的資訊。注意這裡feof判斷的是上一次讀操作移動的FILE指標是否遇到檔案末尾,因此,如果執行如下程式:
char c;
while(!feof(fp))
{
c = fgetc(fp);
printf("%X/n", c);
}
會發現多輸出了一個FF,原因就是在讀完最後一個字元後,fp->flag仍然沒有被置為_IOEOF,因而feof()仍然沒有探測到檔案結尾。直到再次呼叫fgetc()執行讀操作,feof()才能探測到檔案結尾。這樣就多輸出了一個-1(即FF)。正確的寫法應該是:
char c;
c = fgetc(fp);
while(!feof(fp))
{
printf("%X/n", c);
c = fgetc(fp);
}
看到這個問題後去翻了翻自己以前寫的利用socket傳送圖片的程式碼,看有沒有犯類似錯誤,發現採用的是另一種方法:
UINT nSize = 0; UINT nSend = 0; char *szBuff = NULL; //傳送 while (nSize < FindFileData.nFileSizeLow) { szBuff = new char[10240]; memset(szBuff, 0x00, 10240); nSend = file.Read(szBuff, 10240); fwqClientsock.Send(szBuff, nSend);//傳送資料 nSize += nSend; } file.Close(); delete szBuff;
沒有判斷檔案結尾標誌而是判斷已讀大小。