在 C# 中将一个 byte[] 拆分为多个 byte[] 数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11816295/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-09 19:22:50  来源:igfitidea点击:

Splitting a byte[] into multiple byte[] arrays in C#

c#bytearray

提问by JavaScript Developer

I am trying to "chunk" up the bytes of an image. This will allow me to upload a large image in portions. I have the image currently stored as one large byte[]. I would like to split the byte array into byte[]'s with a maxlength of 512 elements. However, I'm not sure how to do this in the most efficient way.

我正在尝试“分块”图像的字节。这将允许我分部分上传大图像。我将图像当前存储为一个大字节 []。我想将字节数组拆分为byte[]'s ,最大长度为 512 个元素。但是,我不确定如何以最有效的方式执行此操作。

Does anyone know how I can do this in the most efficient manner?

有谁知道我如何以最有效的方式做到这一点?

采纳答案by Marc Gravell

The most efficient method would be: not to. If you already have the image as a single byte[] then for local code, just specifying the offset and length (perhaps som ArraySegment-of-byte) is usually sufficient. If your upload API only takes byte[], then you still shouldn't chunk it completely; just use a single 512 buffer and use Buffer.BlockCopy to load it will successive pieces of the data. You may need to resize (Array.Resize) the finalchunk, but at most 2 arrays should be needed.

最有效的方法是:不要。如果您已经将图像作为单个字节 [] 那么对于本地代码,只需指定偏移量和长度(可能是 ArraySegment-of-byte)通常就足够了。如果你的上传 API 只接受 byte[],那么你仍然不应该完全分块;只需使用单个 512 缓冲区并使用 Buffer.BlockCopy 将其加载到连续的数据块中。您可能需要调整 (Array.Resize)最终块的大小,但最多需要 2 个数组。

Even better; avoid needing a byte[] in the first place: consider loading the data via a streaming API (this will work well if the data is coming from a file); just use Read (in a loop, processing the returned value etc) to populate chunks of max 512. For example (untested, just of illustration):

甚至更好;首先避免需要 byte[]:考虑通过流 API 加载数据(如果数据来自文件,这将很好用);只需使用 Read (在循环中,处理返回值等)来填充最大 512 的块。例如(未经测试,仅用于说明):

byte[] buffer = new byte[512];
while(true) {
    int space = 512, read, offset = 0;
    while(space > 0 && (read = stream.Read(buffer, offset, space)) > 0) {
        space -= read;
        offset += read;
    }
    // either a full buffer, or EOF
    if(space != 0) { // EOF - final
       if(offset != 0) { // something to send
         Array.Resize(red buffer, offset);
         Upload(buffer);
       }
       break;
    } else { // full buffer
       Upload(buffer);
    }
}

回答by Chris Gessler

I wrote an extension for this, originally for strings, but decided to make it generic.

我为此编写了一个扩展,最初用于字符串,但决定使其通用。

    public static T[] CopySlice<T>(this T[] source, int index, int length, bool padToLength = false)
    {
        int n = length;
        T[] slice = null;

        if (source.Length < index + length)
        {
            n = source.Length - index;
            if (padToLength)
            {
                slice = new T[length];
            }
        }

        if(slice == null) slice = new T[n];
        Array.Copy(source, index, slice, 0, n);
        return slice;
    }

    public static IEnumerable<T[]> Slices<T>(this T[] source, int count, bool padToLength = false)
    {
        for (var i = 0; i < source.Length; i += count)
            yield return source.CopySlice(i, count, padToLength);
    }

Basically, you can use it like so:

基本上,您可以像这样使用它:

byte[] myBytes; // original byte array

foreach(byte[] copySlice in myBytes.Slices(10))
{
    // do something with each slice
}

Edit: I also provided an answer on SO using Buffer.BlockCopy herebut BlockCopy will only work on byte[]arrays, so a generic version for strings wouldn't be possible.

编辑:我还在此处使用 Buffer.BlockCopy 提供了有关 SO 的答案,但 BlockCopy 仅适用于byte[]数组,因此不可能有字符串的通用版本。

回答by pelitahmet

public static IEnumerable<byte[]> Split(this byte[] value,int bufferLength){
   int countOfArray = value.Length / bufferLength;
   if(value.Length % bufferLength > 0)
      countOfArray ++;
   for(int i=0;i<countOfArray;i++)
   {
      yield return value.Skip(i * bufferLength).Take(bufferLength).ToArray();

   }
}

This is my extension what I used

这是我使用的扩展程序

回答by Hyman Gajanan

I know this is old but needed the same solution and following works perfectly for me hope this helps someone

我知道这是旧的,但需要相同的解决方案,以下对我来说非常有效,希望这对某人有所帮助

private byte[][] ByteArrayToChunks(byte[] byteData, long BufferSize)
{
    byte[][] chunks = byteData.Select((value, index) => new { PairNum = Math.Floor(index / (double)BufferSize), value }).GroupBy(pair => pair.PairNum).Select(grp => grp.Select(g => g.value).ToArray()).ToArray();
    return chunks;
}