2

私の最終的な目標は、protobuf-net と GZipStream を使用してList<MyCustomType>オブジェクトを圧縮し、SQL Server の varbinary(max) フィールドに格納することです。すべてがどのように機能し、どのように組み合わされるかを理解するために、単体テストに取り組んでいます。

対象の .NET フレームワークは 3.5 です。

私の現在のプロセスは次のとおりです。

  1. protobuf-net (良い) でデータをシリアル化します。
  2. #1 のシリアル化されたデータを GZipStream で圧縮します (良い)。
  3. 圧縮データを base64 文字列に変換します (良い)。

この時点で、ステップ 3 の値が varbinary(max) フィールドに格納されます。私はこれを制御できません。手順は、base64 文字列を取得して具象型に逆シリアル化する必要があることから再開されます。

  1. Base 64 文字列をbyte[](良い) に変換します。
  2. GZipStream でデータを解凍します (良い)。
  3. protobuf-net (悪い) でデータをデシリアライズします。

Serializer.Deserialize<string>への呼び出しが返される理由について誰か助けてもらえますnullか? 私はこれにこだわっています。うまくいけば、新鮮な目のセットが役立ちます.

List<T>FWIW、私は T が私が作成したカスタムクラスである場所を使用して、これの別のバージョンを試しましたが、Deserialize<>それでも null を返します。

FWIW 2、data.txt は私の C: にある 4MB のプレーンテキスト ファイルです。

    [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);
                }
            }
        }
    }
4

1 に答える 1

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);
}
于 2013-11-08T21:35:53.580 に答える