文件及;CStdioFile在写入时产生不同的结果&;阅读
据我所知,当使用typeBinary标志创建时,CFile和CStdioFile应该以相同的方式工作,除非后者缓冲数据,因此具有更好的性能 因此,我编写以下代码来确认这一点:文件及;CStdioFile在写入时产生不同的结果&;阅读,file,visual-c++,mfc,cfile,File,Visual C++,Mfc,Cfile,据我所知,当使用typeBinary标志创建时,CFile和CStdioFile应该以相同的方式工作,除非后者缓冲数据,因此具有更好的性能 因此,我编写以下代码来确认这一点: ULONGLONG GetRand(ULONGLONG uMax) { UINT uValue; if (rand_s(&uValue) == 0) return (ULONGLONG)(((double)uValue / (double)UINT_MAX) * uMax);
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();
}
}
ULONGLONG GetRand(ULONGLONG uMax)
{
单位价值;
如果(随机值(&U值)==0)
返回值(ULONGLONG)((双)uValue/(双)UINT_MAX)*uMax);
其他的
返回0;
}
无效校验偏移(CFile&File1、CFile&File2)
{
ULONGLONG uOffset1、uOffset2;
CString-strMsg;
uOffset1=File1.GetPosition();
uOffset2=File2.GetPosition();
如果(uOffset1!=uOffset2)
{
strMsg.Format(_T(“差分偏移量偏移量1=%I64u.偏移量2=%I64u”)、uOffset1、uOffset2);
AfxMessageBox(strMsg);
}
}
无效校验长度(CFile&File1、CFile&File2)
{
ULONGLONG uLength 1、uLength 2;
CString-strMsg;
ulenth1=File1.GetLength();
ulenth2=File2.GetLength();
如果(uLength 1!=uLength 2)
{
strMsg.Format(_T(“差分长度.长度1=%I64u.长度2=%I64u”)、uLength 1、uLength 2);
AfxMessageBox(strMsg);
}
}
无效检查寻道(CFile&File1、CFile&File2、ULONGLONG uOffset)
{
ULONGLONG uOffset1、uOffset2;
CString-strMsg;
uOffset1=File1.Seek(uOffset,CFile::begin);
uOffset2=File2.Seek(uOffset,CFile::begin);
如果(uOffset1!=uOffset2)
{
strMsg.Format(_T(“差分寻道结果.偏移量1=%I64u.偏移量2=%I64u”)、uOffset1、uOffset2);
AfxMessageBox(strMsg);
}
}
无效检查读取(CFile&File1、CFile&File2、UINT uSize)
{
字节lpBuf1[4096],lpBuf2[4096];
UINT uRead1、uRead2;
CString-strMsg;
//从文件1和文件2读取缓冲区
uRead1=File1.Read(lpBuf1,uSize);
uRead2=File2.Read(lpBuf2,uSize);
如果((uRead1!=uRead2)| |(memcmp(lpBuf1,lpBuf2,uRead1)!=0))
{
strMsg.Format(_T(“差异读取结果.uRead1=%u.uRead2=%u.”),uRead1,uRead2);
AfxMessageBox(strMsg);
}
}
void CTestStdioFile64Dlg::OnBnClickedButton1()
{
//TODO:在此处添加控件通知处理程序代码
文件1;
CStdioFile文件2;
单元使用;
字节lpBuf[4096];
CString-strMsg;
如果(文件1.Open(_T(“F:\\Temp\\Test1.dat”),CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive | CFile::typeBinary))
{
如果(文件2.Open(_T(“F:\\Temp\\Test2.dat”),CFile::modeCreate | CFile::modeReadWrite | CFile::shareExclusive | CFile::typeBinary))
{
检查偏移量(文件1、文件2);
检查长度(文件1、文件2);
//写入数据
对于(UINT uIndex=0;uIndex<20000;uIndex++)
{
//为写入生成随机大小
uSize=(UINT)GetRand(4096);
//使用随机数据生成缓冲区
对于(UINT j=0;j
令我惊讶的是,在测试过程中,出现了许多CFileException,因为CStdioFile::Write将写出比预期更少的数据量
此外,还报告了许多不同的读取数据
为什么?当我在调试模式下运行代码时,我得到以下断言 “在连续读写之间刷新。”, !流。是否有任何(\u IOREAD) 原因如下: 从C: (第306页,7.21.5.3) 以更新模式(“+”作为第二个或第三个)打开文件时 上述模式参数值列表中的字符),输入和 可以在相关联的流上执行输出。然而,产出 在没有中间调用的情况下,不得直接跟随输入 fflush功能或文件定位功能(fseek、fsetpos、, (或倒带),输入后不得直接输出 对文件定位函数的中间调用,除非输入 操作遇到endof文件 在代码中,在循环结束时调用
CheckRead
函数,但调用File1.写入和File2.在下一次迭代中写入,而不调用fseek
/刷新
作为快速修复,您可以在CheckRead函数的底部添加以下行:
File1.Seek(0, SEEK_CUR);
File2.Seek(0, SEEK_CUR);
非常感谢你。现在问题消失了。另外,由于CheckSeek函数也可以工作,所以我似乎不需要在写入后调用File1.Flush&File2.Flush。