"在解析完成之前遇到了Stream of Stream." 从文件反序列化时

Oxi*_*ery 4 .net c# visual-studio-2010

我有以下问题:当我启动我的应用程序时,设置从文件加载,所以反序列化,当发生这种情况时,我收到以下错误:

{"End of Stream encountered before parsing was completed."} System.Exception {System.Runtime.Serialization.SerializationException}

序列化代码:

using(FileStream write = new FileStream(SETTINGSPATH,FileMode.Create,FileAccess.Write)
{
  BinaryFormatter formatter = new BinaryFormatter();
  formatter.Serialize(write,settings);
}
Run Code Online (Sandbox Code Playgroud)

反序列化方法:

using (FileStream read = new FileStream(SETTINGSPATH,FileMode.Open,FileAccess.Read))
{
  BinaryFormatter formatter = new BinaryFormatter();
  read.Position = 0;
  settings = (Settings)formatter.Deserialize(read); // settings is declared as Settings object
}
Run Code Online (Sandbox Code Playgroud)

设置类:

using System;
using System.Collections.Generic;  
using System.Linq;
using System.Runtime.Serialization;
using System.Text;

namespace Serie_Counter.Overkoepelend
{
public delegate void SelectedMoveOptionChanged(AutoMoveOption selectedOption, int checkInterval = 30 );

public delegate void EnableAutoMoveChanged(bool EnableAutoMove);

[Serializable]
public class Settings
{
    private string serieListSavePath;
    private bool autoStart;
    private bool enableRember;
    private bool closeWithMainForm;
    private int warningDelay;
    // moving options
    private bool enableAutoMove;
    private string rootFolder;
    private int checkInterval;
    private AutoMoveOption selectedMoveOption;

    public event SelectedMoveOptionChanged selectedMoveOptionChanged;
    public event EnableAutoMoveChanged enableAutoMoveChanged;

    #region Properties

    public string SerieListSavePath
    {
        get
        {
            return serieListSavePath;
        }
        set
        {
            serieListSavePath = value;
        }
    }

    public bool AutoStart
    {
        get
        {
            return autoStart;
        }
        set
        {
            autoStart = value;
        }
    }

    public bool EnableRember
    {
        get
        {
            return enableRember;
        }
        set
        {
            enableRember = value;
        }
    }

    public bool CloseWithMainForm
    {
        get
        {
            return closeWithMainForm;
        }
        set
        {
            closeWithMainForm = value;
        }
    }

    public int WarningDelay
    {
        get
        {
            return warningDelay;
        }
        set
        {
            warningDelay = value;
        }
    }

    public bool EnableAutoMove
    {
        get
        {
            return enableAutoMove;
        }
        set
        {
            enableAutoMove = value;
            if (enableAutoMove != null) enableAutoMoveChanged(value);
        }
    }

    public string RootFolder
    {
        get
        {
            return rootFolder;
        }
        set
        {
            rootFolder = value;
        }
    }

    public int CheckInterval
    {
        get
        {
            return checkInterval;
        }
        set
        {
            checkInterval = value;
        }
    }

    public AutoMoveOption SelectedMoveOption
    {
        get
        {
            return selectedMoveOption;
        }
        set
        {
            selectedMoveOption = value;
            selectedMoveOptionChanged(value, checkInterval);

        }
    }

    #endregion



    public Settings(string serieListSavePath)
    {
        this.serieListSavePath = serieListSavePath;
    }

    public Settings()
    {
        this.serieListSavePath = "series.xml";
        warningDelay = -1;
    }

    [OnDeserialized]
    private void SetValuesOnDeserialized(StreamingContext context)
    {
        selectedMoveOptionChanged = null;
        enableAutoMoveChanged = null;

    }
Run Code Online (Sandbox Code Playgroud)

有人知道为什么会这样吗?

如果您想了解更多信息或代码,请查看http://seriescounter.codeplex.com/

迎接托马斯

编辑:问题可能是反序列化失败,因为我将事件序列化为?我只是通过确保序列化时事件为空来测试它.到目前为止,错误并没有再次发生.

http://seriescounter.codeplex.com/SourceControl/changeset/changes/12646

Han*_*ant 6

更改集12594是您的问题,您将checkIntervalChanged事件添加到Settings类.这为序列化的类添加了一个不可见的字段.但是现在您在设置使用以前版本保存的文件时遇到问题,序列化数据不包含该字段,结果是例外.

你可以像这样拯救它:

    [Serializable]
    public class Settings {
        [NonSerialized]
        private CheckIntervalChanged checkIntervalChangedBacking;

        public event CheckIntervalChanged CheckIntervalChanged {
            add { checkIntervalChangedBacking += value; }
            remove { checkIntervalChangedBacking -= value; }
        }
        // etc..
    }
Run Code Online (Sandbox Code Playgroud)

[NonSerialized]属性现在确保后备字段不会被序列化.你永远不想序列化事件.

一般来说,你需要小心二进制序列化,版本控制很难处理.添加字段可以并且将立即将任何存储的数据转换为垃圾.MSDN库中的" 版本容忍序列化 "部分提供了很好的提示.