VC6,用MFC作了一个多文档CAD类的画图程序,用文档类的void Serialize(CArchive& ar)函数实现序列化;如果Serialize函数内容改变了(比如多存取了一个变量),再打开之前保存的文件的时候会提示:“非预期文件格式”,因此无法打开文件。
问题:在Serialize更新过以后如何兼容之前保存的文件? 请高手们点解一下

解决方案 »

  1.   

    加个统一的头,描述版本。serialize根据此信息分支。
      

  2.   

    IMPLEMENT_SERIAL(CAge, CObject, VERSIONABLE_SCHEMA | 2)
      

  3.   

    具体该怎么实现呢?另外看到一篇文章说是VERSIONABLE_SCHEMA机制有问题,不知道是否真得存在,原文如下:MFC序列化机制中的一个潜在的错误2009-10-23 20:39MFC在IMPLEMENT_SERIAL使用VERSIONABLE_SCHEMA|schema number来提供文件格式的向后兼容.即新的程序既可以读新的文件格式,也可以读较老的文件格式.当它发现要被反序列化的CObject派生类对象内容的shema和程序该类的schema不一致时,如果该类是VERSIONABLE_SCHEMA的(这个信息记录在该类所对应的CRuntimeClass中),那么它仍然调用该类的序列化函数;否则终止反序列化过程,抛出CArchiveException异常,最终向用户报告文件格式错误.
    如果一个类是VERSIONABLE_SCHEMA的,那么该类的反序列化必须根据不同的schma number来进行.就在这里,微软犯了一个潜在的错误,微软对于一个对象只保存一个schema number[对象所属类的],这是不够的.因为一个对象从CObject到对象的实际类型可能不止一级,而每一级的schema number都有变化的可能.当中间层次的类发生变化时,VERSIONABLE_SCHEMA机制就失效了.
    解决这个问题的办法就是自己在每个类层次里序列化类的版本号,根据该版本号进行反序列化,完全忽略MFC的VERSIONABLE_SCHEMA机制.当然,这个问题不可能在MFC框架内得到解决,我觉得MFC开发小组可以有两个办法:一是完全让用户负责文件的向后兼容;一是在MSDN里说明这个潜在的问题,引起程序员的注意. 原文链接:
    http://hi.baidu.com/chendeping/blog/item/323ea55c82aa3c49fbf2c0d5.html
      

  4.   

    如果担心就别用Serialize,自己写个读写类
      

  5.   

    CObject::Serialize(ar);
    if (ar.IsLoading())
    {
    ar >> m_iVersion;// 先读版本号
    if(m_iVersion >= 1)
    {
                         ar >> ......
    }
                    if(m_iVersion >= 2)
    {
                       读你新版本的东西
    }
    }
    else
    {
                   m_iVersion = 1;// 每新一个版本,往后+1 
                   //先写版本号
    ar << m_iVersion;
                    ar << ......
    }