"解析完成前遇到的流结束."从文件反序列化时

本文关键字:quot 结束 反序列化 文件 遇到 | 更新日期: 2023-09-27 18:14:30

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

{"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);
}

反序列化方法:

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
}

设置类:

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;
    }

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

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

问候托马斯。

编辑:问题可能是反序列化失败,因为我序列化事件到?我只是通过确保事件在序列化时为空来测试这一点。到目前为止,这个错误再也没有发生过。

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

"解析完成前遇到的流结束."从文件反序列化时

更改集12594是您的问题,您将checkIntervalChanged事件添加到Settings类中。这也为被序列化的类添加了一个不可见的字段。但现在你有一个问题,设置文件保存在以前的版本,序列化数据不包含该字段,结果是异常。

你可以像这样挽救它:

    [Serializable]
    public class Settings {
        [NonSerialized]
        private CheckIntervalChanged checkIntervalChangedBacking;
        public event CheckIntervalChanged CheckIntervalChanged {
            add { checkIntervalChangedBacking += value; }
            remove { checkIntervalChangedBacking -= value; }
        }
        // etc..
    }

[NonSerialized]属性现在确保后备字段不被序列化。无论如何,你都不会想要序列化事件。

一般来说,您需要小心二进制序列化,版本控制很难处理。添加一个字段可以并且会立即将任何存储的数据变成垃圾。在MSDN库中的"版本容忍序列化"部分有很好的提示。