2

假设我有以下变量:

byte[] fileData;
List<byte> bundleData;

我想取一个连续的部分fileData并将其添加到bundleData. 我目前的方法基本上如下:

int startIndex = 20, endIndex = 80;
byte[] transferredData = new byte[endIndex - startIndex];
Array.Copy(fileData, startIndex, transferredData, 0, transferredData.Length);
bundleData.AddRange(transferredData);

创建中间数组可以正常工作,但它使用了看似不必要的副本。有什么方法可以直接添加数据,而不使用冗余数组?

作为参考,我在这个项目中使用 .NET 2.0。

4

4 回答 4

4

另一种(可能是有效的)方法是使用 LINQ:

bundleData.AddRange(fileData.Skip(startIndex).Take(endIndex - startIndex));
于 2018-11-26T00:19:17.807 回答
2

List<T> 类本质上只是包装了一个 T 数组,当数组已满时,该数组将替换为更大的 T 数组。将字节数组附加到 List<byte> 的最快方法是将字节直接复制到内部字节数组中。

但是 List<T> 类并没有暴露内部数组,所以最好的选择大概是保证列表有足够的容量,不需要多次替换内部数组,然后每个字节一个接一个地添加:

bundleData.Capacity += endIndex - startIndex + 1;

for (int i = startIndex; i <= endIndex; i++)
{
    bundleData.Add(fileData[i]);
}

您还可以尝试使用 AddRange 并提供字节数组的视图:

static IEnumerable<T> Range<T>(this T[] array, int offset, int count)
{
    for (int i = 0; i < count; i++)
    {
        yield return array[offset + i];
    }
}

bundleData.AddRange(fileData.Range(startIndex, endIndex - startIndex + 1));
于 2013-07-16T16:15:53.930 回答
1

如果您实际上不需要 List<byte> 实例,更好的选择可能是MemoryStream 类

内存流类

创建一个后备存储为内存的流。

例子:

MemoryStream bundleData = new MemoryStream();
bundleData.Write(fileData, startIndex, endIndex - startIndex + 1);
于 2013-07-16T16:41:47.020 回答
1

List.AddRange method is implemented as below. I'll add some pseudo code to explain.

ICollection<T> is2 = collection as ICollection<T>;
if(is2!=null)
{
   //then use Array.Copy
}
else
{
 //Loop through GetEnumerator() and calls Insert()
}

So, Intermediate array will be the best idea IMHO since Array Implements ICollection. Hope this helps.

于 2013-07-16T16:32:09.843 回答