2011-02-09 20 views
7

Attualmente sto cercando di serializzare un elenco sempre, si serializza (credo bene), ma quando si deserializzare,DataContractSerializer serializzazione Lista <T> errore

Ci scusiamo per la quantità di codice, ma sono veramente bloccato e non hanno alcun idea perché questo sta accadendo, ho anche provato a cambiare la struttura in una classe e nessun aiuto.

GRAZIE.

ottengo il seguente errore AGGIORNATO

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.` 

sto serializzazione come questo AGGIORNATO

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

sto deserializzazione come questo AGGIORNATO

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

Proprietà

private byte[] _serializedData; 

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

metodi di supporto

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

risposta

1

posso ottenere il campione per funzionare rimuovendo il XmlDictionaryReader e invece alimenta direttamente il flusso di input/output nel DataContractSerializer. Potrebbe essere un difetto in XmlDictionaryReader per grandi raccolte compresse, ma non ne sono sicuro.

Spero che questo aiuti:

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

grazie, che ha funzionato dopo mi sono liberato del XmlDictionaryReader – Kev84

5

E 'perché non si serializzazione l'oggetto (s) completamente. Devi chiudere il/i stream/i dopo la scrittura, specialmente quando usi gzip. Si raccomanda di utilizzare 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

Grazie, ma sto ancora ricevendo questo errore: "Si è verificato un errore di deserializzazione dell'oggetto di tipo System.Collections.Generic.List'1 [[ABCDataValues, AB, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]]. Fine inaspettata del file. Seguenti elementi non sono chiusi: Tempo, DataValues, ArrayOfDataValues ​​'. Vedere codice aggiornato – Kev84

2

dispiace di essere in ritardo a questa domanda.

Il problema con l'approccio iniziale era semplicemente che non si stava scaricando (leggi: smaltimento) il XmlDictionaryWriter.

Questo dovrebbe funzionare (si noti il ​​2 ° con clausola):

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

Spero che questo aiuti qualcuno.

0

Mi sono imbattuto esattamente nello stesso problema e alla fine ho trovato la soluzione: il XmlDictionaryWriter deve essere eliminato/chiuso prima che il flusso in cui si sta scrivendo sia chiuso. L'ho scoperto grazie all'esempio completo trovato a http://www.albahari.com/nutshell/ch15.aspx che sono più completi di quelli MSDN.

Nel codice di esempio, che sarebbe:

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

Sul mio esempio, utilizzando la XmlDictionaryWriter invece di pianura e dallo scrittore XML predefinito mi ha dato solo una diminuzione del ~ 25% nella dimensione del file, ma un fattore 3 durante la lettura di nuovo l'oggetto.

Problemi correlati