How to split a byte array
我在内存中有一个字节数组,可以从文件中读取。我想在某个点(索引)拆分字节数组,而不必只创建一个新的字节数组并一次复制每个字节,从而增加了操作的内存占用量。我想要的是这样的:
1 2 3
| byte[] largeBytes = [1,2,3,4,5,6,7,8,9];
byte[] smallPortion;
smallPortion = split(largeBytes, 3); |
smallPortion等于1,2,3,4
largeBytes等于5,6,7,8,9
仅供参考。 System.ArraySegment<T>结构基本上与上述代码中的ArrayView<T>相同。您可以根据需要使用相同的开箱即用结构。
在使用Linq的C#中,您可以执行以下操作:
1 2
| smallPortion = largeBytes.Take(4).ToArray();
largeBytes = largeBytes.Skip(4).Take(5).ToArray(); |
;)
这就是我要这样做的方式:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| using System;
using System.Collections;
using System.Collections.Generic;
class ArrayView< T > : IEnumerable< T >
{
private readonly T[] array;
private readonly int offset, count;
public ArrayView(T[] array, int offset, int count)
{
this.array = array;
this.offset = offset;
this.count = count;
}
public int Length
{
get { return count; }
}
public T this[int index]
{
get
{
if (index < 0 || index >= this.count)
throw new IndexOutOfRangeException();
else
return this.array[offset + index];
}
set
{
if (index < 0 || index >= this.count)
throw new IndexOutOfRangeException();
else
this.array[offset + index] = value;
}
}
public IEnumerator< T > GetEnumerator()
{
for (int i = offset; i < offset + count; i++)
yield return array[i];
}
IEnumerator IEnumerable.GetEnumerator()
{
IEnumerator< T > enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
yield return enumerator.Current;
}
}
}
class Program
{
static void Main(string[] args)
{
byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
ArrayView<byte> p1 = new ArrayView<byte>(arr, 0, 5);
ArrayView<byte> p2 = new ArrayView<byte>(arr, 5, 5);
Console.WriteLine("First array:");
foreach (byte b in p1)
{
Console.Write(b);
}
Console.Write("\
");
Console.WriteLine("Second array:");
foreach (byte b in p2)
{
Console.Write(b);
}
Console.ReadKey();
}
} |
试试这个:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| private IEnumerable<byte[]> ArraySplit(byte[] bArray, int intBufforLengt)
{
int bArrayLenght = bArray.Length;
byte[] bReturn = null;
int i = 0;
for (; bArrayLenght > (i + 1) * intBufforLengt; i++)
{
bReturn = new byte[intBufforLengt];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLengt);
yield return bReturn;
}
int intBufforLeft = bArrayLenght - i * intBufforLengt;
if (intBufforLeft > 0)
{
bReturn = new byte[intBufforLeft];
Array.Copy(bArray, i * intBufforLengt, bReturn, 0, intBufforLeft);
yield return bReturn;
}
} |
正如Eren所说,您可以使用ArraySegment<T>。这是扩展方法和用法示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| public static class ArrayExtensionMethods
{
public static ArraySegment< T > GetSegment< T >(this T[] arr, int offset, int? count = null)
{
if (count == null) { count = arr.Length - offset; }
return new ArraySegment< T >(arr, offset, count.Value);
}
}
void Main()
{
byte[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 0 };
var p1 = arr.GetSegment(0, 5);
var p2 = arr.GetSegment(5);
Console.WriteLine("First array:");
foreach (byte b in p1)
{
Console.Write(b);
}
Console.Write("\
");
Console.WriteLine("Second array:");
foreach (byte b in p2)
{
Console.Write(b);
}
} |
我不确定您的意思是什么:
I would like to split the byte array at a certain point(index) without having to just create a new byte array and copy each byte at a time, increasing the in memory foot print of the operation.
在大多数语言(当然是C#)中,一旦分配了数组,就无法更改其大小。听起来您正在寻找一种更改数组长度的方法,但是您不能这样做。您还想以某种方式回收数组第二部分的内存,以创建第二个数组,您也不能这样做。
总而言之:只需创建一个新数组即可。
不能。您可能想要的是保持起点和数量。本质上,构建迭代器。如果这是C,则可以只使用std::vector<int>并使用内置的。
在C#中,我将构建一个小的迭代器类,其中包含起始索引,计数并实现IEnumerable<>。
|