«Конец потока обнаружен до завершения анализа».При десериализации из файла - PullRequest
4 голосов
/ 13 ноября 2011

У меня следующая проблема: Когда я запускаю свое приложение, настройки загружаются из файла, поэтому десериализовывается, когда это происходит, я получаю следующую ошибку:

{"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

1 Ответ

6 голосов
/ 13 ноября 2011

Изменение набора 12594 - это ваша проблема, вы добавили событие checkIntervalChanged в класс Settings. Это добавило невидимое в противном случае поле к классу, который также сериализуется. Но теперь у вас есть проблема с настройкой файлов, которые были сохранены в предыдущей версии, данные сериализации не содержат этого поля, исключение составляет результат.

Вы можете спасти его так:

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

        public event CheckIntervalChanged CheckIntervalChanged {
            add { checkIntervalChangedBacking += value; }
            remove { checkIntervalChangedBacking -= value; }
        }
        // etc..
    }

Атрибут [NonSerialized] теперь гарантирует, что вспомогательное поле не будет сериализовано. Вы никогда не захотите сериализовать события.

В общем, вы должны быть осторожны с двоичной сериализацией, с версионностью сложно разобраться. Добавление поля может и мгновенно превратит любые сохраненные данные в мусор. Есть полезные советы в разделе « Сериализация с поддержкой версий » в библиотеке MSDN.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...