2011-02-09 6 views
7

Actualmente estoy tratando de serializar una lista, que serializa (creo que bien), pero cuando se deserializar,DataContractSerializer serialización Lista <T> error al obtener

Lo siento por la cantidad de código, pero estoy realmente atascado y no tienen idea de por qué está sucediendo esto, también traté de cambiar la estructura a una clase y no ayuda.

GRACIAS.

me sale el siguiente error ACTUALIZADO

There was an error deserializing the object of type There was an error deserializing the object of type 
`System.Collections.Generic.List`1[[A.B.C.DataValues, A.V, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]. Unexpected end of file. Following elements are not closed: Time, DataValues, ArrayOfDataValues.` 

estoy serializar como esto ACTUALIZADO

 public void SerializeDataValue(List<DataValues> values) 
      { 
       DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataValues>)); 

       using (MemoryStream stream = new MemoryStream()) 
       { 
        using (GZipStream compress = new GZipStream(stream, CompressionMode.Compress)) 
        { 
         XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter(compress); 
         serializer.WriteObject(w, values); 

        } 
        _serializedData = stream.ToArray(); 
       } 
      } 

estoy deserializar como esto ACTUALIZADO

public List<DataValues> DeserializeDataValue() 
{ 
    if (SerializedData == null || SerializedData.Length == 0) 
    { 
     return new List<DataValues>(); 
    } 
    else 
    { 
     DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataValues>)); 
     using (MemoryStream stream = new MemoryStream(SerializedData)) 
     { 
      using (GZipStream decompress = new GZipStream(stream, CompressionMode.Decompress)) 
      { 
       XmlDictionaryReader r = XmlDictionaryReader.CreateBinaryReader(decompress, XmlDictionaryReaderQuotas.Max); 
       return serializer.ReadObject(r, true) as List<DataValues>; 
      } 
     } 
    } 
} 

Properties

private byte[] _serializedData; 

[DataMember] 
[Browsable(false)] 
public byte[] SerializedData 
{ 
    get { return _serializedData; } 
    set { _serializedData = value; } 
} 

métodos auxiliares

public static byte[] ReadFully(Stream input) 
{ 
    byte[] buffer = new byte[16 * 1024]; 
    input.Position = 0; 
    using (MemoryStream ms = new MemoryStream()) 
    { 
     int read; 
     while ((read = input.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      ms.Write(buffer, 0, read); 
     } 
     return ms.ToArray(); 
    } 
} 

Struct

[DataContract(Name = "DataValues", Namespace = "A.B.C")] 
public struct DataValues 
{ 
    [DataMember] 
    public DateTime Time { get; set; } 
    [DataMember] 
    public Single Value { get; set; } 

    public DataValues(DateTime dateTime, Single value) 
    { 
     Time = dateTime; 
     Value = value; 
    } 
} 

Respuesta

1

puedo conseguir el ejemplo funcione mediante la eliminación de la XmlDictionaryReader y en lugar de alimentar directamente el flujo de entrada/salida en el DataContractSerializer. Puede ser un defecto en el XmlDictionaryReader para grandes colecciones comprimidas, pero no estoy seguro.

Espero que esto ayude:

public void SerializeDataValue(List<DataValues> values) 
      { 
       DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataValues>)); 
        using (MemoryStream stream = new MemoryStream()) 
       { 
        using (GZipStream compress = new GZipStream(stream, CompressionMode.Compress)) 
        { 
         serializer.WriteObject(compress , values); 

        } 
        _serializedData = stream.ToArray(); 
       } 
      } 

    public List<DataValues> DeserializeDataValue() 
    { 
     if (SerializedData == null || SerializedData.Length == 0) 
     { 
      return new List<DataValues>(); 
     } 
     else 
     { 
      DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataValues>)); 
      using (MemoryStream stream = new MemoryStream(SerializedData)) 
      { 
       using (GZipStream decompress = new GZipStream(stream, CompressionMode.Decompress)) 
       { 
        return serializer.ReadObject(decompress , true) as List<DataValues>; 
       } 
      } 
     } 
    } 
+0

gracias, eso funcionó después de que me deshice del XmlDictionaryReader – Kev84

5

Es porque usted no está serialising el objeto (s) completo. Debe cerrar la (s) secuencia (s) después de escribir, especialmente cuando usa gzip. La práctica recomendada es utilizar using:

public void SerializeDataValue(List<DataValues> values) 
{ 
    DataContractSerializer serializer = new DataContractSerializer(typeof(List<DataValues>)); 
    using (MemoryStream stream = new MemoryStream()) 
    { 
     using (GZipStream compress = new GZipStream(stream, CompressionMode.Compress)) 
     { 
      XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter(compress); 
      serializer.WriteObject(w, values); 
     } 
     _serializedData = stream.ToArray(); 
    } 
} 
+0

Gracias, pero sigo recibiendo este error: 'Hubo un error al deserializar el objeto de tipo System.Collections.Generic.List'1 [[ABCDataValues, AB, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]]. Inesperado final de archivo. Los siguientes elementos no están cerrados: Time, DataValues, ArrayOfDataValues. ' Por favor, mira el código actualizado – Kev84

2

Lo sentimos llegar tarde a esta pregunta.

El problema con el enfoque inicial era simplemente que no se estaba lavando (lea: deshacerse) del XmlDictionaryWriter.

Esto debería funcionar (nótese el uso de la cláusula segunda):

using (GZipStream compress = new GZipStream(stream, CompressionMode.Compress)) 
using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter(compress)) 
{ 
    serializer.WriteObject(w, values); 
} 

Espero que esto ayude a alguien.

0

Me encontré exactamente con el mismo problema y finalmente encontré la solución: el XmlDictionaryWriter debe eliminarse/cerrarse antes de que la transmisión en la que está escribiendo se cierre. Descubrí que gracias al minucioso ejemplo encontrado en http://www.albahari.com/nutshell/ch15.aspx que son más completos que los de MSDN.

En el código de ejemplo, que sería:

  using (XmlDictionaryWriter w = XmlDictionaryWriter.CreateBinaryWriter(compress)) 
      { 
       serializer.WriteObject(w, values); 
      } 

En mi propio ejemplo, usando el XmlDictionaryWriter en lugar de la llanura y por el escritor XML por defecto sólo me dio una disminución de ~ 25% en el tamaño del archivo, pero una factor 3 al leer el objeto.

Cuestiones relacionadas