2016-08-10 76 views
1

如何在不使用ToArray()或創建新數組的情況下將list<byte>保存爲MemoryStream()將字節列表轉換爲內存流而不使用ToArray()

這是我目前的方法:

public Packet(List<byte> data) 
{ 
    // Create new stream from data buffer 
    using (Stream stream = new MemoryStream(data.ToArray())) 
    { 
     using (BinaryReader reader = new BinaryReader(stream)) 
     { 
      Length = reader.ReadInt16(); 
      pID = reader.ReadByte(); 
      Result = reader.ReadByte(); 
      Message = reader.ReadString(); 
      ID = reader.ReadInt32(); 
     } 
    } 
} 
+2

爲什麼這麼糟糕?發佈的答案給你的替代品,但我懷疑他們更有效 –

回答

0

爲什麼不循環在列表上?

... 
    using (MemoryStream stream = new MemoryStream(data.Count)) { 
    foreach (var b in data) 
     stream.WriteByte(b); 

    // You may want to return to stream's origin 
    stream.Position = 0; 
    ... 
0

什麼是這樣的:

public Packet(List<byte> data) 
{ 
    using (Stream stream = new MemoryStream()) 
    { 
     // Loop list and write out bytes 
     foreach(byte b in data) 
      stream.WriteByte(b); 

     // Reset stream position ready for read 
     stream.Seek(0, SeekOrigin.Begin); 

     using (BinaryReader reader = new BinaryReader(stream)) 
     { 
      Length = reader.ReadInt16(); 
      pID = reader.ReadByte(); 
      Result = reader.ReadByte(); 
      Message = reader.ReadString(); 
      ID = reader.ReadInt32(); 
     } 
    } 
} 

但是,爲什麼你有擺在首位的列表?難道你不能把它作爲byte[]開始嗎?看看你如何填充這個列表會很有趣。

+0

嗯,我使用Array.resize時,我使用byte []來處理TCP數據包流。這導致我的程序用先前的數組數據覆蓋新的數組 - 如果我在數組創建後添加線程睡眠,這可能會被修復。 和我在互聯網上閱讀的內容,他們說列表是最有效的方法來擁有動態數組。這就是我需要的。 –

1

ToArray解決方案是使用記錄的API的最有效的解決方案。 MemoryStream不會複製數組。它只會存儲它。所以唯一的副本是List<T>.ToArray()

如果你想避免該副本,你需要撬List<T>打開使用反射和訪問支持數組。我建議反對。

而是使用允許您使用合法手段獲取支持數組的集合。寫你自己的,或者首先使用MemoryStream

不管怎樣,A List<T>並不是最有效的字節移動方式。存放它們很好,移動它們通常會有更多的開銷。例如,按字節添加項目將比memcpy慢得多。

+1

如果可能的話,從一開始使用'byte []'而不是'List '。 –

+0

我正在使用byte [],但我需要動態數組,因此列表比使用array.resize多次更高效。 –

+0

@usr,謝謝 - 這個** MemoryStream不會複製數組。它只會存儲它。**完美地回答我的問題。 –

相關問題