0

バイナリシリアル化の方法を学ぼうとしています。

この例外は、以前にシリアル化したオブジェクトを逆シリアル化しようとするたびにスローされます。

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();

         }

現在、例外メッセージは、考えられる原因が、シリアル化と逆シリアル化の間の無効なストリームまたはオブジェクトのバージョン変更であると示しています。シリアル化と逆シリアル化の間でクラスに触れていないので、問題はストリームにあると推測しています。ストリームは無効です(または他の何かです!?)。

誰かが私を正しい方向に向けてください、それは大いにありがたいです。:)

4

2 に答える 2

0

シリアル化のコード例には、日付/時刻を書き込むための次のものがあります。

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

しかし、逆シリアル化コードは次のようになります。

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

つまり、「Datum osnivanja servisa」という名前で値を書き込んでいますが、「Naziv servisa」という名前で読み戻そうとしています。

それがあなたのコードの書き方であり、質問の書き起こしのバグだけではない場合、それが問題の原因であることはほぼ間違いありません。

于 2012-12-24T03:51:18.983 に答える