C# 将字节数组转换为特定长度的数组段
我有一个字节数组,我想以一定大小的新字节数组的形式返回顺序chunck 我试过:C# 将字节数组转换为特定长度的数组段,c#,arrays,loops,split,byte,C#,Arrays,Loops,Split,Byte,我有一个字节数组,我想以一定大小的新字节数组的形式返回顺序chunck 我试过: originalArray = BYTE_ARRAY var segment = new ArraySegment<byte>(originalArray,0,640); byte[] newArray = new byte[640]; for (int i = segment.Offset; i <= segment.Count; i++) { newArray[i] = segment.Ar
originalArray = BYTE_ARRAY
var segment = new ArraySegment<byte>(originalArray,0,640);
byte[] newArray = new byte[640];
for (int i = segment.Offset; i <= segment.Count; i++)
{
newArray[i] = segment.Array[i];
}
显然,这只会从原始数组创建一个包含前640字节的数组。最后,我需要一个循环,它遍历前640个字节并返回这些字节的数组,然后遍历下一个640个字节并返回这些字节的数组。其目的是向服务器发送消息,每条消息必须包含640字节。我不能保证原始数组长度可以被640整除
谢谢如果你真的想从每个640字节的数据块中创建新的数组,那么你正在寻找。跳过并。接受
这里有一个工作示例和一个我一起破解的示例
using System;
using System.Linq;
using System.Text;
using System.Collections;
using System.Collections.Generic;
class MainClass {
public static void Main (string[] args) {
// mock up a byte array from something
var seedString = String.Join("", Enumerable.Range(0, 1024).Select(x => x.ToString()));
var byteArrayInput = Encoding.ASCII.GetBytes(seedString);
var skip = 0;
var take = 640;
var total = byteArrayInput.Length;
var output = new List<byte[]>();
while (skip + take < total) {
output.Add(byteArrayInput.Skip(skip).Take(take).ToArray());
skip += take;
}
output.ForEach(c => Console.WriteLine($"chunk: {BitConverter.ToString(c)}"));
}
}
实际上,正确地使用ArraySegment可能会更好,除非这是学习LINQ扩展的任务。如果速度不是问题的话
var bytes = new byte[640 * 6];
for (var i = 0; i <= bytes.Length; i+=640)
{
var chunk = bytes.Skip(i).Take(640).ToArray();
...
}
您可以像这样编写通用帮助器方法:
public static IEnumerable<T[]> AsBatches<T>(T[] input, int n)
{
for (int i = 0, r = input.Length; r >= n; r -= n, i += n)
{
var result = new T[n];
Array.Copy(input, i, result, 0, n);
yield return result;
}
}
byte[] byteArray = new byte[123456];
// ... initialise byteArray[], then:
var listOfChunks = byteArray.InChunksOf(640).ToList();
或者,如果您想要批次列表,只需执行以下操作:
List<byte[]> listOfBatches = AsBatches(byteArray, 640).ToList();
您可以这样使用:
public static IEnumerable<T[]> AsBatches<T>(T[] input, int n)
{
for (int i = 0, r = input.Length; r >= n; r -= n, i += n)
{
var result = new T[n];
Array.Copy(input, i, result, 0, n);
yield return result;
}
}
byte[] byteArray = new byte[123456];
// ... initialise byteArray[], then:
var listOfChunks = byteArray.InChunksOf(640).ToList();
[编辑]将循环终止符从r>n更正为r>=n。首先,请注意:ArraySegment仍使用与原始数组相同的缓冲区。这通常正是您想要的,但不是您在问题的其余部分中所描述的。是的,为了正确回答这一问题,我们需要知道,您是否需要制作原始数据的实际副本,或者在块中引用原始数据就够了?b你能为块使用IEnumerable吗,还是必须是数组?你使用的是什么版本的c和.Net?这些问题的答案将决定最有效的解决方案。a需要是副本b需要是字节数组c和asp.net core mcc appAlso如果缓冲区不是640的倍数,剩余字节会发生什么变化?它们只是被忽略了,还是被添加到640个字节,然后被发送,或者其他什么?我假设它只是被忽略了。我正试图根据本文档“”将音频写入websocket,该文档要求消息大小为640字节。如果原始字节数组的长度不能被640整除,该文档将如何处理原始字节数组的其余部分?我只想忽略最后的“批处理”,它不等于640字节。@HarryStudio这正是它要做的-任何剩余的字节都将被忽略。太棒了,我将在今晚晚些时候或明天早上测试代码
public static class ArrayExt
{
public static IEnumerable<T[]> InChunksOf<T>(this T[] input, int n)
{
for (int i = 0, r = input.Length; r >= n; r -= n, i += n)
{
var result = new T[n];
Array.Copy(input, i, result, 0, n);
yield return result;
}
}
}
byte[] byteArray = new byte[123456];
// ... initialise byteArray[], then:
var listOfChunks = byteArray.InChunksOf(640).ToList();