簡體   English   中英

在C#中發送/接收GZip壓縮的MSMQ消息

[英]Send/Receive GZip compressed MSMQ messages in C#

我正在嘗試將大對象(> 30MB)發送到MSMQ隊列。 由於大量的數據,我們正試圖發送的想法是在發送對象之前先將它們壓縮,然后在接收端將其解壓縮。

但是,將壓縮流寫入message.BodyStream屬性似乎可以工作,但不能從那里讀出。 我不知道怎么了

Message l_QueueMessage = new Message();
l_QueueMessage.Priority = priority;

using (MessageQueue l_Queue = CreateQueue())
{
    GZipStream stream = new GZipStream(l_QueueMessage.BodyStream, CompressionMode.Compress);

    Formatter.Serialize(stream, message);

    l_Queue.Send(l_QueueMessage);
}

Formatter是BinaryFormatter類型的全局屬性。 這用於序列化/反序列化為我們要發送/接收的對象的類型,例如“ ProductItem”。

接收端如下所示:

GZipStream stream = new GZipStream(l_Message.BodyStream, CompressionMode.Decompress);

object decompressedObject = Formatter.Deserialize(stream);

ProductItem l_Item = decompressedObject as ProductItem;

m_ProductReceived(sender, new MessageReceivedEventArgs<ProductItem>(l_Item));

l_ProductQueue.BeginReceive();

我收到EndOfStreamException "{"Unable to read beyond the end of the stream."}試圖在System.IO.BinaryReader.ReadByte()上反序列化

實際上,使用messageBodyStream屬性可以繞過message.Formatter,因為我在GZipStream中使用了自己的ser / deser機制,所以我沒有將其初始化為任何東西。 但是,我不確定這是否是正確的方法。

我想念什么? 謝謝!

在您的原始代碼中,問題在於您需要關閉GZipStream才能正確編寫GZip頁腳,然后才可以發送它。 如果不這樣做,最終將發送無法反序列化的字節。 這就是為什么以后發送成功的新代碼起作用的原因。

好,我做了這項工作。 關鍵是將接收器上的解壓縮流轉換為byte []數組。 然后反序列化開始起作用。

發件人代碼(請注意在發送消息之前關閉流):

using (MessageQueue l_Queue = CreateQueue())
{
    using (GZipStream stream = new GZipStream(l_QueueMessage.BodyStream, CompressionMode.Compress, true))
    {
        Formatter.Serialize(stream, message);
    }

    l_Queue.Send(l_QueueMessage);
}

接收端(注意我如何將流轉換為byte []然后反序列化):

using (GZipStream stream = new GZipStream(l_QueueMessage.BodyStream, CompressionMode.Decompress))
{
    byte[] bytes = ReadFully(stream);

    using (MemoryStream ms = new MemoryStream(bytes))
    {
        decompressedObject = Formatter.Deserialize(ms);
    }
}

但是,仍然不知道為什么使用ReadFully()函數而不是Stream.CopyTo()可以正常工作。 有沒有人?

順便說一句,ReadFully()是一個從Stream創建字節[]的函數。 我必須在http://www.yoda.arachsys.com/csharp/readbinary.html上感謝Jon Skeet。 謝謝!

嘗試分開壓縮和發送:

byte[] binaryBuffer = null;
using (MemoryStream compressedBody = new MemoryStream()) 
{
    using(GZipStream stream = new GZipStream(compressedBody, CompressionMode.Compress))
    {
        Formatter.Serialize(compressedBody, message); 
        binaryBuffer = compressedBody.GetBuffer();
    }
}

using (MessageQueue l_Queue = CreateQueue())        
{            
    l_QueueMessage.BodyStream.Write(binaryBuffer, 0, binaryBuffer.Length);
    l_QueueMessage.BodyStream.Seek(0, SeekOrigin.Begin);
    l_Queue.Send(l_QueueMessage);
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM