为了账号安全,请及时绑定邮箱和手机立即绑定

将字节数组转换为一定长度的数组段

将字节数组转换为一定长度的数组段

C#
ABOUTYOU 2022-01-09 10:52:02
我有一个字节数组,我想返回一定大小的顺序块(以新字节数组的形式)。我试过:originalArray = BYTE_ARRAYvar 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 个字节并返回一个 THOSE 字节数组。这样做的目的是向服务器发送消息,每条消息必须包含 640 个字节。我不能保证原始数组长度可以被 640 整除。谢谢
查看完整描述

3 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

如果速度不是问题


var bytes = new byte[640 * 6];


for (var i = 0; i <= bytes.Length; i+=640)

{

   var chunk = bytes.Skip(i).Take(640).ToArray();

   ...

}

或者你可以使用


跨度切片法

Buffer.BlockCopy(Array, Int32, Array, Int32, Int32) 方法

跨度


Span<byte> bytes = arr; // Implicit cast from T[] to Span<T>


...


slicedBytes = bytes.Slice(i, 640);

块复制


请注意,这可能是 3 个中最快的


var chunk = new byte[640]

Buffer.BlockCopy(bytes, i, chunk, 0, 640);


查看完整回答
反对 回复 2022-01-09
?
UYOU

TA贡献1878条经验 获得超4个赞

如果您真的想从每个 640 字节块中创建新数组,那么您正在寻找.Skip并且.Take


这是我一起破解的一个工作示例(以及示例的副本)。


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 扩展的任务。


查看完整回答
反对 回复 2022-01-09
?
撒科打诨

TA贡献1934条经验 获得超2个赞

你可以像这样编写一个通用的辅助方法:


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;

    }

}

然后你可以foreach循环使用它:


byte[] byteArray = new byte[123456];


foreach (var batch in AsBatches(byteArray, 640))

{

    Console.WriteLine(batch.Length); // Do something with the batch.

}

或者,如果您想要批次列表,请执行以下操作:


List<byte[]> listOfBatches = AsBatches(byteArray, 640).ToList();

如果您想变得花哨,可以将其作为扩展方法,但仅在您将大量使用它时才建议这样做(不要为您只会在一个地方调用的东西创建扩展方法!)。


在这里,我更改了名称InChunksOf()以使其更具可读性:


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();

[编辑] 将循环终止符从 更正r > n为r >= n。


查看完整回答
反对 回复 2022-01-09
  • 3 回答
  • 0 关注
  • 196 浏览

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号