2011-02-09 5 views
7

Obecnie próbuję serializować listy, to serializes (myślę, że w porządku), ale gdy deserializowania,DataContractSerializer szeregowania Lista <T> coraz błąd

Niestety dla ilości kodu, ale jestem naprawdę zatrzymany i nie mają Pomysł, dlaczego tak się dzieje, próbowałem również zmienić strukturę w klasę i bez pomocy.

DZIĘKI.

otrzymuję następujący błąd AKTUALIZACJA

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

ja szeregowania tak AKTUALIZACJA

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

jestem deserializacji jak ten AKTUALIZACJA

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

pomocnicze Metody

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

Odpowiedz

1

mogę uzyskać próbkę do pracy poprzez usunięcie XmlDictionaryReader i zamiast bezpośrednio podawanie strumienia wejścia/wyjścia do DataContractSerializer. Może to być defekt w XmlDictionaryReader dla dużych skompresowanych zbiorów, ale nie jestem pewien.

Nadzieja to pomaga:

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

dzięki, że pracował po pozbyłem się XmlDictionaryReader – Kev84

5

To dlatego, że nie są SZEREGOWANIE obiekt (-y) do końca. Po zapisaniu musisz zamknąć strumień (y), szczególnie gdy używasz gzip. Zalecaną praktyką jest stosowanie 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

Dzięki, ale nadal otrzymuję ten błąd: "Wystąpił błąd podczas deserializacji obiektu typu System.Collections.Generic.List'1 [[ABCDataValues, AB, Version = 1.0.0.0, Culture = neutral, PublicKeyToken = null]]. Nieoczekiwany koniec pliku. Następujące elementy nie są zamknięte: Time, DataValues, ArrayOfDataValues. ' Proszę zobaczyć zaktualizowany kod – Kev84

2

Niestety za późno na to pytanie.

Problem z początkowym podejściem polegał po prostu na tym, że nie spłukiwałeś (czytaj: wyrzucaj) XmlDictionaryWriter.

To powinno działać (zauważ 2nd użyciu klauzuli):

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

Hope this helps kogoś.

0

Wpadłem dokładnie na ten sam problem iw końcu znalazłem rozwiązanie: XmlDictionaryWriter musi zostać usunięty/zamknięty, zanim Strumień, w którym piszesz, zostanie zamknięty. Odkryłem, że dzięki dokładnemu przykładowi znalezionemu pod http://www.albahari.com/nutshell/ch15.aspx, który jest bardziej kompletny niż te z MSDN.

W kodzie próbki, które mogłyby być:

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

Na własnym przykładzie, używając XmlDictionaryWriter zamiast zwykłego i domyślnie Xml pisarza tylko dał mi spadek ~ 25% rozmiaru pliku, ale współczynnik 3 podczas odczytywania obiektu.