[英]How do I efficiently get a subset of a byte array (first N elements) in C#?
我有一個最大大小為1K的字節數組緩沖區。 我想寫出數組的一個子集(子集的開頭總是元素0,但我們感興趣的長度是變量)。
這里的應用程序是壓縮。 我將緩沖區傳遞給壓縮函數。 為簡單起見,假設壓縮將導致數據相等或小於1K字節。
byte[] buffer = new byte[1024];
while (true)
{
uncompressedData = GetNextUncompressedBlock();
int compressedLength = compress(buffer, uncompressedData);
// Here, compressedBuffer[0..compressedLength - 1] is what we're interested in
// There's a method now with signature Write(byte[] compressedData) that
// I won't be able to change. Short of allocating a custom sized buffer,
// and copying data into the custom sized buffer... is there any other
// technique I could use to only expose the data I want?
}
我真的很想在這里避免復制 - 看起來完全沒必要,因為所有需要的數據都已經在buffer
了。
Buffer.BlockCopy將是我的選擇。
Microsoft示例: http : //msdn.microsoft.com/en-us/library/system.buffer.blockcopy.aspx
const int INT_SIZE = 4;
int[] arr = { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 };
Buffer.BlockCopy(arr, 3 * INT_SIZE, arr, 0 * INT_SIZE, 4 * INT_SIZE);
foreach (int value in arr)
Console.Write("{0} ", value);
// The example displays the following output:
// 8 10 12 14 10 12 14 16 18 20
您的代碼如下所示:
uncompressedData = GetNextUncompressedBlock();
int compressedLength = compress(buffer, uncompressedData);
Buffer.BlockCopy(buffer, 0, buffer, 0, compressedLength);
如果您無法更改方法簽名,那么您就會陷入困境。 您無法在類型為byte []的字節數組上創建“視圖”。 對此的理想解決方案是采用ArraySegment<byte>
或byte[]
后跟偏移量和計數的操作。 如果你真的無法改變Write方法,那么遺憾的是你不得不創建一個新數組並將數據復制到它。
你無法做到這一點。 Array.Resize而不是更改數組的長度,只需將其復制到新的數組實例。
但是,您可以使用具有更好性能的Buffer類 :
Buffer提供了將字節從一個基本類型數組復制到另一個基本類型數組,從數組中獲取一個字節,在數組中設置一個字節以及獲取數組長度的方法。 與System.Array類中的類似方法相比,此類為操作基元類型提供了更好的性能。
這符合您的需求,因為您有一個字節數組,而byte是一種基本類型。
byte[] b = new Byte[] {1, 2, 3, 4, 5};
IEnumerable<Byte> middle = b.Skip(2).Take(3);
這應該讓你得到你喜歡的任何中間部分。 這很可能是副本,但我認為你不應該試圖避免這種情況。
如果方法簽名是(byte[])
,除了復制之外你不能做任何事情。
如果你可以改變簽名:
流支持編寫數組的子集,因此像Stream.Write這樣的簽名並不罕見:
public abstract void Write( byte[] buffer, int offset, int count)
另一種選擇是傳遞IEnumerable<byte>
這樣你就可以按照自己想要的方式切片。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.