假设我有以下变量:
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。
答案 0 :(得分:2)
列表&lt; T&gt; class本质上只是包装一个T数组,当数组已满时,该数组被更大的T数组替换。将字节数组追加到List&lt; byte&gt;的最快方法将字节直接复制到内部字节数组中。
然而,列表&lt; T&gt; class不公开内部数组,所以最好的选择可能是确保列表有足够的容量,不需要多次替换内部数组,然后逐个添加每个字节:
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));
答案 1 :(得分:1)
List.AddRange方法实现如下。我将添加一些伪代码来解释。
ICollection<T> is2 = collection as ICollection<T>;
if(is2!=null)
{
//then use Array.Copy
}
else
{
//Loop through GetEnumerator() and calls Insert()
}
因此,自阵列实现ICollection以来,中间阵列将是最好的想法。 希望这会有所帮助。
答案 2 :(得分:1)
如果您实际上不需要List&lt; byte&gt;例如,更好的选择可能是MemoryStream class:
MemoryStream类
创建其后备存储为内存的流。
示例:的
MemoryStream bundleData = new MemoryStream();
bundleData.Write(fileData, startIndex, endIndex - startIndex + 1);
答案 3 :(得分:1)
另一种(可能有效的)方法是使用LINQ:
bundleData.AddRange(fileData.Skip(startIndex).Take(endIndex - startIndex));