如何在 C# 上划分数组?

How to Divide an array on c#?

我必须编写一个程序来读取图像并将其放入字节数组中

var Imagenoriginal = File.ReadAllBytes("10M.bmp");

然后将该字节数组分成 3 个不同的数组,以便将每个新数组发送到其他计算机(使用管道)在那里进行处理,最后将它们带回原始计算机并最终给出结果。 但我的问题是,如果所选图像可以具有不同的大小,我该如何做一个能够将字节数组划分为三个不同字节数组的算法。 感谢您的帮助,祝您有美好的一天。 =)

你可以这样试试:

public static IEnumerable<IEnumerable<T>> DivideArray<T>(this T[] array, int size)
{
    for (var i = 0; i < (float)array.Length / size; i++)
    {
        yield return array.Skip(i * size).Take(size);
    }
}

这样的调用:

var arr = new byte[] {1, 2, 3, 4, 5,6};
var dividedArray = arr.DivideArray(3);

这是一个 LINQ 方法:

public List<List<byte>> DivideArray(List<byte> arr)
{
    return arr
             .Select((x, i) => new { Index = i, Value = x })
             .GroupBy(x => x.Index / 100)
             .Select(x => x.Select(v => v.Value).ToList())
             .ToList();
}

您可以划分数组的长度,因此您有三个整数 n1n2n3,它们的总和为 array.Length。那么,使用 LINQ 的这段代码应该会有帮助:

var arr1 = sourceArray.Take(n1).ToArray();
var arr2 = sourceArray.Skip(n1).Take(n2).ToArray();
var arr3 = sourceArray.Skip(n1+n2).Take(n3).ToArray();

现在,在 arr1arr2arr3 中,您将拥有源数组的三个部分。你需要使用 LINQ,所以在代码的开头不要忘记 using System.Linq;.

您是否考虑过使用 Streams?您可以扩展 Stream class 以提供所需的行为,如下所示:

public static class Utilities
{
    public static IEnumerable<byte[]> ReadBytes(this Stream input, long bufferSize)
    {
        byte[] buffer = new byte[bufferSize];
        int read;

        while ((read = input.Read(buffer, 0, buffer.Length)) > 0)
        {
            using (MemoryStream tempStream = new MemoryStream())
            {
                tempStream.Write(buffer, 0, read);
                yield return tempStream.ToArray();
            }            
        }
    }

    public static IEnumerable<byte[]> ReadBlocks(this Stream input, int nblocks)
    {
        long bufferSize = (long)Math.Ceiling((double)input.Length / nblocks);
        return input.ReadBytes(bufferSize);
    }
}
  • ReadBytes 扩展方法使用指定的 bufferSize 读取 input 流和 returns 其数据作为字节数组序列。

  • ReadBlocks 扩展方法使用适当的缓冲区大小调用 ReadBytes,以便序列中的元素数等于 nblocks.

然后您可以使用 ReadBlocks 来实现您想要的:

public class Program
{
    static void Main()
    {
        FileStream inputStream = File.Open(@"E:M.bmp", FileMode.Open);
        const int nblocks = 3;

        foreach (byte[] block in inputStream.ReadBlocks(nblocks))
        {
            Console.WriteLine("{0} bytes", block.Length);
        }
    }
}

注意 ReadBytes 如何使用 tempStreamread 将从 输入流 中读取的字节写入内存,然后再将它们转换为字节数组,它解决了评论中提到的剩余字节的问题。