protobuf-net在调用Deserialize时返回null

时间:2013-11-08 21:29:32

标签: c# serialization protobuf-net

我的最终目标是使用protobuf-net和GZipStream来尝试压缩List<MyCustomType>对象以存储在SQL Server的varbinary(max)字段中。我正在进行单元测试,以了解一切是如何工作的。

目标.NET框架是3.5。

我目前的流程是:

  1. 使用protobuf-net(好)序列化数据。
  2. 使用GZipStream(好)压缩来自#1的序列化数据。
  3. 将压缩数据转换为base64字符串(好)。
  4. 此时,步骤#3的值将存储在varbinary(max)字段中。我无法控制这一点。这些步骤恢复,需要获取base64字符串并将其反序列化为具体类型。

    1. 将基本64字符串转换为byte[](好)。
    2. 使用GZipStream(好)解压缩数据。
    3. 使用protobuf-net(坏)反序列化数据。
    4. 有人可以协助调用Serializer.Deserialize<string>的电话回复null吗?我坚持这个,希望一双新的眼睛会有所帮助。

      FWIW,我使用List<T>尝试了另一个版本,其中T是我创建的自定义类,而Deserialize<>仍然返回null。

      FWIW 2,data.txt是一个4MB的纯文本文件,位于我的C:。

          [Test]
          public void ForStackOverflow()
          {
              string data = "hi, my name is...";
              //string data = File.ReadAllText(@"C:\Temp\data.txt");
      
              string serializedBase64;
      
              using (MemoryStream protobuf = new MemoryStream())
              {
                  Serializer.Serialize(protobuf, data);
      
                  using (MemoryStream compressed = new MemoryStream())
                  {
                      using (GZipStream gzip = new GZipStream(compressed, CompressionMode.Compress))
                      {
                          byte[] s = protobuf.ToArray();
                          gzip.Write(s, 0, s.Length);
                          gzip.Close();
                      }
      
                      serializedBase64 = Convert.ToBase64String(compressed.ToArray());
                  }
              }
      
              byte[] base64byteArray = Convert.FromBase64String(serializedBase64);
      
              using (MemoryStream base64Stream = new MemoryStream(base64byteArray))
              {
                  using (GZipStream gzip = new GZipStream(base64Stream, CompressionMode.Decompress))
                  {
                      using (MemoryStream plainText = new MemoryStream())
                      {
                          byte[] buffer = new byte[4096];
                          int read;
      
                          while ((read = gzip.Read(buffer, 0, buffer.Length)) > 0)
                          {
                              plainText.Write(buffer, 0, read);
                          }
      
                          // why does this call to Deserialize return null?
                          string deserialized = Serializer.Deserialize<string>(plainText);
      
                          Assert.IsNotNull(deserialized);
                          Assert.AreEqual(data, deserialized);
                      }
                  }
              }
          }
      

1 个答案:

答案 0 :(得分:4)

因为写完之后你没有倒回plainText。实际上,整个Stream是不必要的 - 这有效:

using (MemoryStream base64Stream = new MemoryStream(base64byteArray))
{
    using (GZipStream gzip = new GZipStream(
        base64Stream, CompressionMode.Decompress))
    {
        string deserialized = Serializer.Deserialize<string>(gzip);

        Assert.IsNotNull(deserialized);
        Assert.AreEqual(data, deserialized);
    }
}

同样,这应该适用于序列化:

using (MemoryStream compressed = new MemoryStream())
{
    using (GZipStream gzip = new GZipStream(
        compressed, CompressionMode.Compress, true))
    {
        Serializer.Serialize(gzip, data);
    }

    serializedBase64 = Convert.ToBase64String(
        compressed.GetBuffer(), 0, (int)compressed.Length);
}