"The end of the stream, met before parsing, has been completed." When deserializing from a file

I have the following problem: when I run my application, the settings are loaded from the file, so deserialized when this happens, I got the following error:

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

Serialization code:

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

Deserialization Method:

 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 } 

Settings Class:

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

Does anyone know why this is happening?

If you need more information or code, please check http://seriescounter.codeplex.com/

hello Thomas

EDIT: Could the problem be that deserialization fails because I am serializing events? I just tested this, making sure that when serialized, the events are zero. and so far the error has not been repeated.

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

+4
source share
1 answer

The change task 12594 is your problem, you added the checkIntervalChanged event to the Settings class. This added an invisible field to the class, which is also serialized. But now you have a problem with setting up files that were saved with the previous version, serialization data does not contain this field, an exception is the result.

You can save it like this:

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

The [NonSerialized] attribute now guarantees that the support field will not be serialized. In any case, you never want to serialize events.

In general, you need to be careful with binary serialization, versioning is difficult. Adding a field can instantly turn any stored data into unwanted data. The Version tolerant serialization "section of the MSDN library has some good tips.

+6
source

Source: https://habr.com/ru/post/1380990/


All Articles