我在內存中有一個字節數組,從文件中讀取。我想在某個點(索引)分割字節數組,而不必創建一個新的字節數組並一次複製每個字節,從而增加了操作的內存足跡。我想是這樣的:如何分割字節數組
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
我在內存中有一個字節數組,從文件中讀取。我想在某個點(索引)分割字節數組,而不必創建一個新的字節數組並一次複製每個字節,從而增加了操作的內存足跡。我想是這樣的:如何分割字節數組
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
這是我會怎麼做:
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("\n");
Console.WriteLine("Second array:");
foreach (byte b in p2)
{
Console.Write(b);
}
Console.ReadKey();
}
}
你不能。你可能想要的是保持一個起點和數量的項目;本質上來說,構建迭代器。如果這是C++,則可以使用std::vector<int>
並使用內置的。在C#中,我會構建一個小的迭代器類,它包含開始索引,計數並實現IEnumerable<>
。
我不知道你的意思是:
我想字節數組在某一點分裂(指數)而不必創建一個新的字節數組並一次複製每個字節,從而增加了操作的內存佔用量。
在大多數語言中,肯定是C#,一旦數組被分配,就沒有辦法改變它的大小。這聽起來像你正在尋找一種方法來改變數組的長度,你不能。你也想以某種方式回收數組第二部分的內存,以創建第二個數組,這也是你無法做到的。
總結:只需創建一個新的數組。
僅供參考。 System.ArraySegment<T>
結構基本上與上面的代碼中的ArrayView<T>
是一樣的。如果你願意,你可以用相同的方式使用這個開箱即用的結構。
在C#中使用LINQ,你可以這樣做:
smallPortion = largeBytes.Take(4).ToArray();
largeBytes = largeBytes.Skip(4).Take(5).ToArray();
;)
該OP想知道如何做到這一點**,而不必創建一個新的字節數組,並一次複製每個字節**但這正是你的LINQ代碼所做的。兩次。 – 2011-12-21 22:00:56
..這幫助我解決了一個我沒有通過`ArraySegment
試試這個:
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 said,你可以使用ArraySegment<T>
。以下是擴展方法和用法示例:
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("\n");
Console.WriteLine("Second array:");
foreach (byte b in p2)
{
Console.Write(b);
}
}
有趣。太糟糕了,我在做這個項目時沒有看到這個。無論如何感謝您的信息。 – 2009-11-02 17:23:10