二进制流损坏的可能原因是什么?

时间:2012-12-24 01:23:34

标签: .net serialization c++-cli runtime binary-serialization

我正在尝试学习如何进行二进制序列化。

每次我尝试反序列化我之前序列化的对象时,都会抛出此异常:

Binary stream '161' does not contain a valid BinaryHeader. Possible causes are invalid 
stream or object version change between serialization and deserialization.

这是我班级的标题:

    [Serializable]
    public ref class Servis{
        String ^_nazivServisa;
        DateTime ^_datumOsnivanjaServisa;
        double _popustZaStalneKlijente;          
        [NonSerialized] List<Izvjestaj ^> ^_izvjestaji;
        [NonSerialized] List<StalniKlijent ^> ^_stalniKlijenti;
        [NonSerialized] List<Vozilo ^> ^_poznataVozila;

这是GetObjectData方法,在同一个类中设置为public:

            virtual void GetObjectData(SerializationInfo^ info, StreamingContext context){
                info->AddValue("Naziv servisa", _nazivServisa);
                info->AddValue("Datum osnivanja servisa", _datumOsnivanjaServisa->ToString());
                info->AddValue("Popust za stalne klijente", _popustZaStalneKlijente);
            }

这是用于反序列化的构造函数:

        protected:
        Servis(SerializationInfo ^info, StreamingContext context){
                _nazivServisa = info->GetString("Naziv servisa");
                _datumOsnivanjaServisa = Convert::ToDateTime(info->GetString("Popust za stalne klijente"));
                _popustZaStalneKlijente = info->GetDouble("Popust za stalne klijente");
                _izvjestaji=gcnew List<Izvjestaj ^>;
                _stalniKlijenti = gcnew List<StalniKlijent ^>;
                _poznataVozila = gcnew List<Vozilo ^>;
            }

这是我尝试打开文件并反序列化的代码块;如果文件不存在,则会显示一个新对话框以输入一些数据,然后将文件序列化

            BinaryFormatter ^b = gcnew BinaryFormatter;
        try{
            FileStream ^fs = gcnew FileStream("..\\Datoteke\\Servis.dat", FileMode::Open);              
            _servis = dynamic_cast<Servis ^>(b->Deserialize(fs));   
            fs->Close();
            }
        catch(FileNotFoundException ^exc){
            KreirajServis();
            try{
                FileStream ^fs = gcnew FileStream("..\\Datoteke\\Servis.dat", FileMode::Create);                    
                b->Serialize(fs, _servis);
                fs->Close();
                }
            }
           }


private: void KreirajServis(){
         PrvoPokretanje ^p = gcnew PrvoPokretanje();
         p->ShowDialog();
         _servis=p->dajServis();

         }

现在,异常消息说可能的原因是序列化和反序列化之间的无效流或对象版本更改。 由于我没有在序列化和反序列化之间触及我的类,我猜测问题在于流,它是无效的(或者它是其他东西!?)。

请有人,请指出我正确的方向,我将不胜感激。 :)

2 个答案:

答案 0 :(得分:1)

DateTime是一个值类。所以最简单的方法是在Servis instand中使用sintax并使用处理程序来使用DateTime

答案 1 :(得分:0)

序列化的代码示例用于编写日期/时间:

info->AddValue("Datum osnivanja servisa", _datumOsnivanjaServisa->ToString());

但反序列化代码为:

_datumOsnivanjaServisa = Convert::ToDateTime(info->GetString("Naziv servisa"));

所以你要写一个名为“Datum osnivanja servisa”的值,但试着用“Naziv servisa”这个名字读回来。

如果您的代码是如何编写的,而不仅仅是您的问题中的转录错误,那么它几乎肯定是您问题的原因。