C# &引用;解析完成前遇到的流结束。";从文件反序列化时
我有以下问题:当我启动我的应用程序时,设置是从一个文件加载的,因此被反序列化,当这种情况发生时,我得到以下错误:C# &引用;解析完成前遇到的流结束。";从文件反序列化时,c#,.net,visual-studio-2010,C#,.net,Visual Studio 2010,我有以下问题:当我启动我的应用程序时,设置是从一个文件加载的,因此被反序列化,当这种情况发生时,我得到以下错误: {“解析完成前遇到流结束。”}System.Exception{System.Runtime.Serialization.SerializationException} 序列化代码: using(FileStream write = new FileStream(SETTINGSPATH,FileMode.Create,FileAccess.Write) { BinaryForm
{“解析完成前遇到流结束。”}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;
}
有人知道为什么会这样吗
如果您想要更多信息或代码,请检查
问候
托马斯
编辑:问题可能是反序列化失败,因为我将事件序列化为?
我只是通过确保序列化时事件为null来测试这一点。到目前为止,错误没有再次发生
更改集12594是您的问题,您已将checkIntervalChanged事件添加到设置类中。这也为被序列化的类添加了一个不可见的字段。但是现在您在设置使用以前版本保存的文件时遇到问题,序列化数据不包含该字段,结果是异常 你可以这样拯救它:
[Serializable]
public class Settings {
[NonSerialized]
private CheckIntervalChanged checkIntervalChangedBacking;
public event CheckIntervalChanged CheckIntervalChanged {
add { checkIntervalChangedBacking += value; }
remove { checkIntervalChangedBacking -= value; }
}
// etc..
}
[NonSerialized]属性现在可以确保支持字段不会被序列化。无论如何,您都不想序列化事件
通常,您需要小心处理二进制序列化,版本控制很难处理。添加字段可以并将立即将任何存储的数据变成垃圾。MSDN库中的“”部分提供了很好的提示。您是否检查了文件是否存在且未损坏?如果您只是存储设置,那么经验法则是使用可读格式(如XML)保存设置。请发布用于序列化和保存设置的代码。在你发布的codeplex链接中不容易找到。我怀疑它可能缺少一个
Flush
。此外,您没有正确触发enableAutoMoveChanged
事件。您应该首先将事件复制到局部变量var ev=enableAutoMoveChanged
然后检查ev
是否不为空,然后触发ev(值)代码>我检查文件是否存在序列化代码:使用(FileStream write=new FileStream(SETTINGSPATH,FileMode.Create,FileAccess.write)){BinaryFormatter formatter=new BinaryFormatter();formatter.Serialize(write,settings);}
可能是因为我将事件序列化到了,所以出现了错误吗?我将序列化为可读格式(xml/json)并查看设置有什么问题。添加到类中的字段不应影响从旧版本反序列化,因为未知字段将只填充其默认值。另外,通过使用属性的字段说明符(即事件声明上的[field:NonSerialized]
),不序列化事件更容易。我遇到了相同的错误,找到了此页面。然而,事实证明,我的问题是,我添加了一个新类,但忘记了向该类添加[Serializable]属性,因此它一开始没有正确序列化。然后,当它尝试反序列化时,我得到了这个错误。一旦将[Serializable]属性添加到类中,一切正常。