Сериализация объектов в файл

403
25 мая 2017, 07:36

Пришла в голову идея организовать промежуточное сохранение данных, вроде экземпляров класса, в файле, для дальнейшей работы с ними. Задача подразумевает, что в файл может быть сохранено несколько объектов, соответственно размер сериализованного объекта сохраняется и пристыковывается спереди к нему в теле файла. В двух словах хочется сделать следующую структуру файла: [sizeObjectN][serializationObjectN][sizeObject(N+1)][serializtionObject(N+1)] и т.п.

Проблема кроется в попытке десериализовать объект, полученный из потока чтения файла, прилетает эксепшн с сообщением: "Конец потока обнаружен до завершения разбора"

Краткий код с сериализацией одного объекта прилагаю:

Сам класс объекта:

[Serializable]
class MySerializtionClass
{
    private string name;
    private int age;
    public MySerializtionClass(string Name, int Age)
    {
        this.name = Name;
        this.age = Age;
    }
    public string Name
    {
        get { return name; }
    }
    public int Age
    {
        get { return age; }
    }
}

Ну и программа, с попыткой запихнуть в файл объект и извлечь его оттуда:

class Program
{
    static void Main(string[] args)
    {
        // Сериализация
        MySerializtionClass myClass = new MySerializtionClass("Tom", 17);
        Console.WriteLine("Объект создан");
        BinaryFormatter formatter = new BinaryFormatter();
        long size = 0;
        byte[] buffer;
        using (MemoryStream stream = new MemoryStream())
        {
            formatter.Serialize(stream, myClass);
            size = stream.Length;
            Console.WriteLine(size);
            stream.Read(buffer = new byte[size], 0, (int)size);
        }
        using (FileStream fs = new FileStream("People.data001", FileMode.OpenOrCreate))
        {
            byte[] iSize = new byte[4];
            iSize = BitConverter.GetBytes(buffer.Length);
            fs.Write(iSize, 0, 4);
            fs.Write(buffer, 0, buffer.Length);
            Console.WriteLine("Файл записан");
        }

        // Десериализация
        using (FileStream fs = new FileStream("People.data001", FileMode.OpenOrCreate))
        {
            byte[] Size = new byte[4];
            fs.Read(Size, 0, 4);
            int iSize = BitConverter.ToInt32(Size,0);
            byte[] Buffer = new byte[iSize];
            fs.Read(Buffer, 0, iSize);
            using (MemoryStream stream = new MemoryStream())
            {
                stream.Write(Buffer, 0, iSize);
                ///////////////////////////////////////////
                // Вот в этом самом месте прилетает ексепшн
                ///////////////////////////////////////////
                myClass = (MySerializtionClass)formatter.Deserialize(stream);                    
            }
        }
        Console.WriteLine("Класс десериализован");
        Console.WriteLine("Имя: {0}, Возраст: {1}", myClass.Name, myClass.Age);
    }
}

Помогите разобраться.

P.S. У меня подозрение что я записываю в файл пустоту размером в 182 байта..

Answer 1

Передвиньте поток обратно на начало

using (MemoryStream stream = new MemoryStream())
{
  stream.Write(Buffer, 0, iSize);
  stream.Position = 0; // !!!
  myClass = (MySerializtionClass)formatter.Deserialize(stream);                    
}
READ ALSO
Фокус только на форме

Фокус только на форме

Есть форма, установил свойство KeyPreviewПоставил обработчик KeyPress

259
Как вычислить возраст в С#?

Как вычислить возраст в С#?

почему при вычитании двух дат типа DateTime получается значение типа TimeSpan, и как мне получить отсюда результат типа DateTime?

301
Проблема при обновлении данных в ADO.NET

Проблема при обновлении данных в ADO.NET

Пытаюсь выполнить SQL запрос, при выполнении метода Fill, почему-то выбивает ошибку:

282
Размещение C# на сервере

Размещение C# на сервере

Создаю бота для вк, который меняет название группы при помощи C# ASPNET MVC

280