int nLeft = nCount;
PBYTE pBuf = (PBYTE)lpBuf;
//读完nCount个字节的数据
while(nLeft > 0)
{
//CSocket的Receive,阻塞操作,读取到数据才继续
nRead = m_pSocket->Receive(pBuf, nLeft);
if (nRead == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
ASSERT(FALSE);
}
else if (nRead == 0)
{
return nCount - nLeft;
}
nLeft -= nRead;
pBuf += nRead;
}
return nCount - nLeft;
}
//和一个CArchive对象关联使用
//读取数据,能读多少是多少
nRead = m_pSocket->Receive(lpBuf, nCount, 0);
if (nRead == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
ASSERT(FALSE);
}
return nRead;
}
文件写的实现
void CSocketFile::Write(const void* lpBuf, UINT nCount)
{
ASSERT (m_pSocket!=NULL);
//CSocket的函数Send,阻塞操作,发送完毕才继续
int nWritten = m_pSocket->Send(lpBuf, nCount);
if (nWritten == SOCKET_ERROR)
{
int nError = m_pSocket->GetLastError();
AfxThrowFileException(CFileException::generic, nError);
}
}
从CSockefFile的读写实现可以看出,CSocketFile如果独立使用,在Read操作时可能出现无限等待,因为数据是分多个消息多次送达的,没有读取到指定长度的数据并不表示数据读取完毕。但是和CArchive配合使用,则仅仅读取到数据就返回。至于数据是否读取完毕,可以使用CArchive的IsBufferEmpty函数来判断。
其他CFile界面,CSocketFile没有实现。
从CScocketFile的设计和实现来看,CSocketFile是使用CSocket的一个很好的例子,也是使用CFile的一个例子。