1. 程式人生 > >C++ 檔案流處理

C++ 檔案流處理

包含於#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;

沒有判斷檔案結尾標誌而是判斷已讀大小。