簡體   English   中英

如何在C#中有效地獲取字節數組(前N個元素)的子集?

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

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