据我了解,当使用 typeBinary 标志创建时,CFile 和 CStdioFile 应该以相同方式工作,除了后者正在缓冲数据,因此具有更好的性能。
所以我写了以下代码来确认这一点:
ULONGLONG GetRand(ULONGLONG uMax)
{
UINT uValue;
if (rand_s(&uValue) == 0)
return (ULONGLONG)(((double)uValue / (double)UINT_MAX) * uMax);
else
return 0;
}
void CheckOffset(CFile& File1, CFile& File2)
{
ULONGLONG uOffset1, uOffset2;
CString strMsg;
uOffset1 = File1.GetPosition();
uOffset2 = File2.GetPosition();
if (uOffset1 != uOffset2)
{
strMsg.Format(_T("Difference offset. Offset1 = %I64u. Offset2 = %I64u."), uOffset1, uOffset2);
AfxMessageBox(strMsg);
}
}
void CheckLength(CFile& File1, CFile& File2)
{
ULONGLONG uLength1, uLength2;
CString strMsg;
uLength1 = File1.GetLength();
uLength2 = File2.GetLength();
if (uLength1 != uLength2)
{
strMsg.Format(_T("Difference length. Length1 = %I64u. Length2 = %I64u."), uLength1, uLength2);
AfxMessageBox(strMsg);
}
}
void CheckSeek(CFile& File1, CFile& File2, ULONGLONG uOffset)
{
ULONGLONG uOffset1, uOffset2;
CString strMsg;
uOffset1 = File1.Seek(uOffset, CFile::begin);
uOffset2 = File2.Seek(uOffset, CFile::begin);
if (uOffset1 != uOffset2)
{
strMsg.Format(_T("Difference seek results. Offset1 = %I64u. Offset2 = %I64u."), uOffset1, uOffset2);
AfxMessageBox(strMsg);
}
}
void CheckRead(CFile& File1, CFile& File2, UINT uSize)
{
BYTE lpBuf1[4096], lpBuf2[4096];
UINT uRead1, uRead2;
CString strMsg;
// Read buffer from file1 & file2
uRead1 = File1.Read(lpBuf1, uSize);
uRead2 = File2.Read(lpBuf2, uSize);
if ((uRead1 != uRead2) || (memcmp(lpBuf1, lpBuf2, uRead1) != 0))
{
strMsg.Format(_T("Difference read results. uRead1 = %u. uRead2 = %u."), uRead1, uRead2);
AfxMessageBox(strMsg);
}
}
void CTestStdioFile64Dlg::OnBnClickedButton1()
{
// TODO: Add your control notification handler code here
CFile File1;
CStdioFile File2;
UINT uSize;
BYTE lpBuf[4096];
CString strMsg;
if (File1.Open(_T("F:\\Temp\\Test1.dat"), CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive | CFile::typeBinary))
{
if (File2.Open(_T("F:\\Temp\\Test2.dat"), CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive | CFile::typeBinary))
{
CheckOffset(File1, File2);
CheckLength(File1, File2);
// Write data
for (UINT uIndex = 0; uIndex < 20000; uIndex ++)
{
// Generate a randome size for write
uSize = (UINT)GetRand(4096);
// Generate buffer with random data
for (UINT j = 0; j < uSize; j++)
lpBuf[j] = (BYTE)GetRand(255);
// Write buffer to file1 & file2
File1.Write(lpBuf, uSize);
File2.Write(lpBuf, uSize);
File1.Flush();
File2.Flush();
CheckOffset(File1, File2);
CheckLength(File1, File2);
// Seek to a randome location
CheckSeek(File1, File2, GetRand(File1.GetLength()));
// Generate a randome size for read
uSize = (UINT)GetRand(4096);
CheckRead(File1, File2, uSize);
CheckOffset(File1, File2);
}
File2.Close();
}
File1.Close();
}
}
令我惊讶的是,在测试过程中,由于 CStdioFile::Write 写入的数据量比预期的少,因此引发了许多 CFileException。
还报告了许多不同的读取数据。
为什么?