[英]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.