Pregunta

Tengo una matriz de bytes en la memoria, leída de un archivo.Me gustaría dividir la matriz de bytes en un punto determinado (índice) sin tener que simplemente crear una nueva matriz de bytes y copiar cada byte a la vez, aumentando la huella de memoria de la operación.Lo que me gustaría es algo como esto:

byte[] largeBytes = [1,2,3,4,5,6,7,8,9];  
byte[] smallPortion;  
smallPortion = split(largeBytes, 3);  

smallPortion sería igual a 1,2,3,4
largeBytes sería igual a 5,6,7,8,9

¿Fue útil?

Solución

Así es como lo haría:

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

Otros consejos

Para su información. System.ArraySegment<T> La estructura es básicamente la misma que ArrayView<T> en el código anterior.Puede utilizar esta estructura lista para usar de la misma manera, si lo desea.

En C# con Linq puedes hacer esto:

smallPortion = largeBytes.Take(4).ToArray();
largeBytes = largeBytes.Skip(4).Take(5).ToArray();

;)

Prueba este:

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;
        }
    }

No estoy seguro de lo que quieres decir con:

Me gustaría dividir la matriz de bytes en un punto determinado (índice) sin tener que simplemente crear una nueva matriz de bytes y copiar cada byte a la vez, aumentando la huella de memoria de la operación.

En la mayoría de los lenguajes, ciertamente C#, una vez que se ha asignado una matriz, no hay forma de cambiar su tamaño.Parece que estás buscando una manera de cambiar la longitud de una matriz, pero no puedes.También desea reciclar de alguna manera la memoria de la segunda parte de la matriz, para crear una segunda matriz, lo cual tampoco puede hacer.

En resumen:simplemente crea una nueva matriz.

Como Eren dijo, puedes usar ArraySegment<T>.A continuación se muestra un método de extensión y un ejemplo de uso:

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

No puedes.Lo que quizás quieras es mantener un punto de partida y una cantidad de elementos;en esencia, construir iteradores.Si esto es C++, puedes usar std::vector<int> y utilizar los integrados.

En C#, crearía una pequeña clase iteradora que contiene el índice de inicio, el recuento y las implementaciones. IEnumerable<>.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top