2013-08-22 54 views
0

我正在做一些數據分塊,在響應中發送二進制數據時,我看到一個有趣的問題。我可以確認字節數組的長度低於4兆字節的數據限制,但是當我收到消息時,它的總大小超過4兆字節。WCF是否填充SOAP消息中的所有字節數組?

對於下面的示例,我使用了最大的塊大小,以便我可以在收到可用塊的同時說明問題。

Actual Message Size

二進制數據的大小爲3040870在服務端和客戶端(一旦消息被反序列化)。但是,我也可以確認字節數組實際上只有4兆字節(這是通過從消息中複製二進制數據並將其粘貼到文本文件中完成的)。

Actual Size in Bytes

那麼,是WCF造成這些問題的,如果是這樣,有什麼我可以做,以防止它?如果不是,可能會導致我這邊的通貨膨脹?

謝謝!

回答

3

在SOAP消息中發送byte[]的通常方式是base64-encode的數據。這種編碼比二進制編碼多佔33%的空間,這幾乎可以精確地解決尺寸差異。

您可以稍微調整最大大小或塊大小,以便最終結果在正確範圍內,或使用其他編碼(例如, MTOM,以消除這33%的開銷。

+0

正是我需要的。謝謝! – elucid8

0

如果你被困在肥皂中,你可以補償緩衝區開銷Tim S.在.Net中使用System.IO.Compression庫討論過 - 在構建和發送肥皂之前,首先使用compress函數信息。

你會用這種壓縮:

public static byte[] Compress(byte[] data) 
{ 
    MemoryStream ms = new MemoryStream(); 
    DeflateStream ds = new DeflateStream(ms, CompressionMode.Compress); 
    ds.Write(data, 0, data.Length); 
    ds.Flush(); 
    ds.Close(); 
    return ms.ToArray(); 
} 

在接收端,你會用它來解壓:

public static byte[] Decompress(byte[] data) 
{ 
    const int BUFFER_SIZE = 256; 
    byte[] tempArray = new byte[BUFFER_SIZE]; 
    List<byte[]> tempList = new List<byte[]>(); 
    int count = 0; 
    int length = 0; 

    MemoryStream ms = new MemoryStream(data); 
    DeflateStream ds = new DeflateStream(ms, CompressionMode.Decompress); 

while ((InlineAssignHelper(count, ds.Read(tempArray, 0, BUFFER_SIZE))) > 0) { 
    if (count == BUFFER_SIZE) { 
     tempList.Add(tempArray); 
     tempArray = new byte[BUFFER_SIZE]; 
    } else { 
     byte[] temp = new byte[count]; 
     Array.Copy(tempArray, 0, temp, 0, count); 
     tempList.Add(temp); 
    } 
    length += count; 
} 

    byte[] retVal = new byte[length]; 

    count = 0; 
    foreach (byte[] temp in tempList) { 
     Array.Copy(temp, 0, retVal, count, temp.Length); 
     count += temp.Length; 
} 

return retVal; 
}