В настоящее время я работаю над проектом с MFC, и я заметил кое-что странное, что, очевидно, было там в течение нескольких лет.Когда я запускаю .exe программы, она делает n разных вещей, включая чтение файла .DAT и его сохранение.Если файл не существует, программа попытается найти его, но безуспешно выдает это исключение CFile: файл не найден.Что правильно, потому что его не существует.Сначала мне нужно выполнить некоторые операции для генерации этого файла, процесс сохранения работает нормально.Когда файл существует, и я снова запускаю программу, он должен прочитать файл, но появляется это исключение CArchive: Неверный формат файла.И я не понимаю, почему.
Это Serialize ():
//Fruits.cpp
void CFruits::Serialize(CArchive &ar)
{
int nVersion = 0;
CObject::Serialize(ar);
ar.SerializeClass(GetRuntimeClass());
if(ar.IsStoring())
{
ar.Write(&m_bInit,sizeof(bool));
ar.Write(&m_bYummy,sizeof(bool));
ar.Write(&m_bAcid, sizeof(bool));
ar.Write(&m_bFresh,sizeof(bool));
...
...
...
ar<<m_cType;
ar<<m_cColour;
ar<<m_cFlavor;
ar<<m_cPrice;
ar<<m_cQuantity;
}
else
{
nVersion = ar.GetObjectSchema();
ar.Read(&m_bInit,sizeof(bool));
ar.Read(&m_bYummy,sizeof(bool));
ar.Read(&m_bAcid, sizeof(bool));
ar.Read(&m_bFresh,sizeof(bool));
...
...
...
if( nVersion >= 2 || nVersion < 0)
ar<<m_cType;
else
m_cType=0;
if (nVersion >= 3 || nVersion < 0)
ar<<m_cColour;
else
m_cColour=0;
if (nVersion >= 4 || nVersion < 0)
ar<<m_cFlavor;
else
ar<<m_cFlavor=0;
if( nVersion >= 5 || nVersion < 0)
{
ar<<m_cPrice;
ar<<m_cQuantity;
}
else
{
m_cPrice=0;
m_cQuantity=0;
}
}
m_oSales.Serialize(ar);
m_oAdmin.Serialize(ar);
...
...
}
IMPLEMENT_SERIAL(CVehiculo,CObject,VERSIONABLE_SCHEMA | 6)
Это SerializeElements:
//Fruits.cpp
void AFXAPI SerializeElements(CArchive &ar,CFruits * fruits,int ncount)
{
try
{
for(cont=0;cont<ncount;cont++)
fruits[cont].Serialize(ar);
}
catch(CArchiveException *AE)
{
//Here it stores the exception in a Log. Exception 5
}
}
serializeElements используется для храненияи прочитайте файл n раз, как указано здесь в заголовочном файле фруктов:
//Fruits.h
class CFruits : public CObject
{
public:
CFruits();
CFruits(const CFruits &O);
virtual ~CFruits();
void operator = (const CFruits &O);
void Serialize(CArchive &ar);
protected:
DECLARE_SERIAL(CFruits)
};
void AFXAPI SerializeElements(CArchive &ar,CFruits * fruits,int ncount);
typedef CArray<CFruits, CFruitso&> TArrayFruits;
Значения этого массива и методы, используемые для вызова сериализации, определены здесь в моей главной функции:
//main.h
#include "CFruits.h"
class CMain : public CDialog
{
// Construction
public:
enum T_Fruits { eFruitsOnLine, eFruitsIng, eFruitsTra, eFruitsAnt, eFruitsP3, eFruitsP2, eFruitsP1, eFruitsC1, eFruitsC0, eFruitsEscape, eFruitsVideo};
private:
void StoreFruits();
void ReadFruits();
Предполагается, что цикл for SerializeElements должен выполняться 11 раз, но я заметил, что он делает это только 1 раз, затем версия схемы изменяется на -1 (изначально 6, потому что мне удалось отследить значение),Это происходит только при чтении файла.Я пробовал следующее: я не могу использовать отладку, поэтому я должен использовать журналы, я помещал журнал после каждого предложения в функцию Serialize (), я нашел, что, кажется, проблема, эту строку:
ar.SerializeClass(GetRuntimeClass());
Я использовал try-catch и обнаружил, что когда это предложение происходит, оно выдает исключение, поэтому оно не продолжает читать.Это момент, когда версия меняется на -1.Я попытался изменить это на:
ar.SerializeClass(RUNTIME_CLASS(CFruits));
Это тот же результат, я прочитал много фрум, пытаясь найти ответ, но я не могу этого сделать.Я прочитал документацию и нашел ее здесь: https://docs.microsoft.com/en-us/cpp/mfc/reference/carchive-class?view=vs-2019#serializeclass
Как и ReadClass, SerializeClass проверяет, что информация о заархивированном классе совместима с вашим классом времени выполнения.Если он несовместим, SerializeClass сгенерирует исключение CArchiveException.
Но это не имеет смысла для меня, потому что оно не перестает хранить.Стоит ли искать что-то еще?
Спасибо
РЕДАКТИРОВАТЬ: я публикую методы Store и Read
void CMain::ReadFruits()
{
CString CSerror, sFileName;
CString sDebug;
try
{
sFileName.Format("FRUITS%03d.DAT",GetNumT());
CFile fFruitsTag(sFileName,CFile::modeRead);
CArchive ar(&fFruitsTag,CArchive::load);
m_vFruits.Serialize(ar);
ar.Close();
fFruitsTag.Close();
}
catch(CFileException *FE)
{
...
}
catch(CArchiveException *AE)
{
...
}
}
void CMain::StoreFruits()
{
CString CSerror, sFileName;
try
{
if(!m_bStoringFruits)
{
sFileName.Format("FRUITS%03d.DAT",GetNumT());
m_bStoringFruits=true;
CFile fFruitsTag(sFileName,CFile::modeCreate|CFile::modeWrite);
CArchive ar(&fFruitsTag,CArchive::store);
m_vFruits.Serialize(ar);
ar.Close();
fFruitsTag.Close();
m_bStoringFruits=false;
}
}
catch(CFileException *FE)
{
...
}
catch(CArchiveException *AE)
{
...
}
catch(CException *e)
{
...
}
}