C# 如何拆分字节数组
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20797/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to split a byte array
提问by Keith Sirmons
I have a byte array in memory, read from a file. 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. What I would like is something like this:
我在内存中有一个字节数组,从文件中读取。我想在某个点(索引)拆分字节数组,而不必只创建一个新的字节数组并一次复制每个字节,从而增加操作的内存足迹。我想要的是这样的:
byte[] largeBytes = [1,2,3,4,5,6,7,8,9];
byte[] smallPortion;
smallPortion = split(largeBytes, 3);
smallPortion
would equal 1,2,3,4largeBytes
would equal 5,6,7,8,9
smallPortion
等于 1,2,3,4largeBytes
等于 5,6,7,8,9
采纳答案by Micha? Piaskowski
This is how I would do that:
这就是我将如何做到的:
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();
}
}
回答by Stu
You can't. What you might want is keep a starting point and number of items; in essence, build iterators. If this is C++, you can just use std::vector<int>
and use the built-in ones.
你不能。您可能想要的是保留一个起点和项目数量;本质上,构建迭代器。如果这是 C++,你可以使用std::vector<int>
和使用内置的。
In C#, I'd build a small iterator class that holds start index, count and implements IEnumerable<>
.
在 C# 中,我会构建一个小的迭代器类,其中包含开始索引、计数和实现IEnumerable<>
。
回答by Outlaw Programmer
I'm not sure what you mean by:
我不确定你的意思:
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.
我想在某个点(索引)拆分字节数组,而不必只创建一个新的字节数组并一次复制每个字节,从而增加操作的内存足迹。
In most languages, certainly C#, once an array has been allocated, there is no way to change the size of it. It sounds like you're looking for a way to change the length of an array, which you can't. You also want to somehow recycle the memory for the second part of the array, to create a second array, which you also can't do.
在大多数语言中,当然是 C#,一旦分配了数组,就无法更改它的大小。听起来您正在寻找一种方法来更改数组的长度,但您不能这样做。您还想以某种方式回收数组第二部分的内存,以创建第二个数组,这也是您无法做到的。
In summary: just create a new array.
总之:只需创建一个新数组。
回答by Eren Ers?nmez
FYI. System.ArraySegment<T>
structure basically is the same thing as ArrayView<T>
in the code above. You can use this out-of-the-box structure in the same way, if you'd like.
供参考。 System.ArraySegment<T>
结构基本上与ArrayView<T>
上面的代码相同。如果您愿意,您可以以同样的方式使用这种开箱即用的结构。
回答by Alireza Naghizadeh
In C# with Linq you can do this:
在带有 Linq 的 C# 中,您可以执行以下操作:
smallPortion = largeBytes.Take(4).ToArray();
largeBytes = largeBytes.Skip(4).Take(5).ToArray();
;)
;)
回答by Robert Wisniewski
Try this one:
试试这个:
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;
}
}
回答by orad
As Eren said, you can use ArraySegment<T>
. Here's an extension method and usage example:
正如艾伦所说,你可以使用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);
}
}