formatter deserialize дает: Конец потока обнаружен до завершения синтаксического анализа

Я пытаюсь десериализовать объект, который я сохранил в файл (с помощью Binary Formatter). Что бы я ни пытался, я получаю исключение: Конец потока обнаружен до завершения синтаксического анализа.

У меня есть следующие строки кода:

public static T DeserializeFromBinaryFile<T>(string fileName)
{
    T instance = default(T);
    FileStream fs = new FileStream(fileName, FileMode.Open);
    try
    {
        BinaryFormatter formatter = new BinaryFormatter();
        instance = (T)formatter.Deserialize(fs);
    }
    catch{}
    finally
    {
        fs.Close();
    }

    return instance;
}

Я также пробовал:

public static T DeserializeFromBinaryFile<T>(string fileName)
{
    T instance = default(T);
    FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.Read);
    MemoryStream ms = new MemoryStream();
    try
    {
        byte[] bytes = new byte[fs.Length];
        fs.Read(bytes, 0, (int)fs.Length);
        ms.Write(bytes, 0, (int)fs.Length);
        ms.Position = 0;
        ms.Seek(0, SeekOrigin.Begin); 
    }
    catch { }

    try
    {
        BinaryFormatter formatter = new BinaryFormatter();
        instance = (T)formatter.Deserialize(ms);
    }
    catch { }
    finally
    {
        ms.Close();
        fs.Close();
    }

    return instance;
}

Но что бы я ни делал, всегда получаю исключение:

Конец потока обнаружен до завершения синтаксического анализа

ДОПОЛНЕНИЕ. Я только что провел дополнительные тесты. Если у меня есть простой объект, всего несколько свойств, он отлично работает. Используя более (большой) сложный объект с инкапсулированными другими объектами, перечислениями и т. д., я получаю исключение.


person royu    schedule 02.04.2013    source источник


Ответы (3)


Попробуйте установить position в 0 для вашего потока внутри второго блока try/catch:

BinaryFormatter b = new BinaryFormatter();
s.Position = 0;
return (YourObjectType)b.Deserialize(s);
person Otacon    schedule 02.04.2013

Вы пытались десериализовать поток файлов, а не поток памяти? меня устраивает.

FileStream fs = new FileStream(fileName, FileMode.Open);
fs.position=0;
instance = (T)formatter.Deserialize(fs);

С уважением

person namenotallowed    schedule 11.06.2014

Каждый член класса, подлежащий сериализации, должен иметь атрибут [Serializable()] или быть помечен [NonSerialized]. Обратите внимание, что перечисления и все простые встроенные типы уже сериализуемы и не требуют атрибута [Serializable()].

Пример ниже дает ту же ошибку. Раскомментируйте [Serializable()] над public class B, и десериализация пройдет без ошибок.

*Невозможно с уверенностью сказать, является ли это причиной вашей ошибки, поскольку вы не предоставили образец класса, вызвавшего ошибку.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; 

//[Serializable()]
public class B
{
    public int y = 2;
}
[Serializable()]
public class A
{
    public int x = 2;
    /*[NonSerialized]*/ public B b;
    public static T DeserializeFromBinaryFile<T>(string fileName)
    {
        T instance = default(T);
        FileStream fs = new FileStream(fileName, FileMode.Open);
        try
        {
            BinaryFormatter formatter = new BinaryFormatter();
            instance = (T)formatter.Deserialize(fs);
        }
        catch (System.Exception ex)
        {
            Console.WriteLine(ex.Message);
        }
        finally
        {
            fs.Close();
        }

        return instance;
    }
    public static void SerializeBinaryFile<T>(string fileName,T t)
    {
        try
        {
            using (FileStream fs = File.Open(fileName, FileMode.Create))
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(fs, t);
            }
        }
        catch (System.Exception ex)
        {

        }
    }
}

class Program
{
    static void Main(string[] args)
    {
        A testA = new A();
        A.SerializeBinaryFile("test.dat", testA);
        A testReadA = A.DeserializeFromBinaryFile<A>("test.dat");
    }
}

https://msdn.microsoft.com/en-us/library/ms973893.aspx

person Roci    schedule 22.08.2015