使用 MFC CFile 进行文件读取写入

File read write using MFC CFile

本文关键字:读取 文件 MFC CFile 使用      更新时间:2023-10-16

我想知道为什么下面的代码没有将正确的数据写入文件。如果我将缓冲区大小更改为更大的大小,则此代码可以正常工作。

对于

下面的代码,如果我尝试读取小于 500 字节的文件,它工作得很好,但对于更大的文件,我必须增加缓冲区。我在阅读循环中缺少什么?

  const int iBuffSiz = 500;
  char chBuffer[iBuffSiz];
  memset(chBuffer, 0, sizeof(chBuffer));
    CFile file;
  CFile fileO;
  if(file.Open(XML_FILE_NAME, CFile::modeRead | CFile::typeBinary) == FALSE)
  {
    return;
  }
  if(fileO.Open(XML_FILE_NAME_O, CFile::modeCreate | CFile::modeWrite | CFile::typeBinary) == FALSE)
  {
    return;
  }
  while(file.Read(chBuffer, iBuffSiz) > 0)
  {
    try{
      UINT iCount = strlen(chBuffer);
      fileO.Write(chBuffer, iCount);
    }
    catch (CFileException *exp)
    {
      TCHAR szCause[255];
      exp->GetErrorMessage(szCause, 255);
    }
  }
  //Closing file handle and socket after complete file send
  file.Close();
  fileO.Close();

CFile::Read不会为空终止缓冲区,因此缓冲区strlen可以大于缓冲区,它会运行缓冲区溢出。有一种方法可以解决这个问题,但strlen仍然不适用于二进制文件,这次缓冲区被剪得太短了。因此,最好使用返回的值CFile::Read

UINT iCount;
while( ( iCount = file.Read(chBuffer, iBuffSiz) ) > 0 )
{
   try
   {
      fileO.Write(chBuffer, iCount);
   }
   catch (CFileException *exp)
   {
      TCHAR szCause[255];
      exp->GetErrorMessage(szCause, 255);
   }
}

同意 Barmark 的观点,即 CFile::Read 返回的计数可能超过指定的缓冲区大小

我有更多的观点是

您需要在将缓冲区写入另一个文件后清除缓冲区,因为它指向您已经写入目标文件的字符串,因此您可能无法获得所需文件的确切副本。

  while(file.Read(chBuffer, iBuffSiz-1) > 0)
  {
    try{
      UINT iCount = strlen(chBuffer);
      fileO.Write(chBuffer, iCount);
      memset(chBuffer, 0, sizeof(chBuffer));
    }
    catch (CFileException *exp)
    {
      TCHAR szCause[255];
      exp->GetErrorMessage(szCause, 255);
    }
  }