Question

J'ai un tableau d'octets en mémoire, lu à partir d'un fichier.Je voudrais diviser le tableau d'octets à un certain point (index) sans avoir à simplement créer un nouveau tableau d'octets et copier chaque octet à la fois, augmentant ainsi l'empreinte mémoire de l'opération.Ce que j'aimerais, c'est quelque chose comme ça :

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

smallPortion serait égal à 1,2,3,4
largeBytes serait égal à 5,6,7,8,9

Était-ce utile?

La solution

Voici comment je procéderais:

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

Autres conseils

POUR VOTRE INFORMATION. System.ArraySegment<T> la structure est fondamentalement la même chose que ArrayView<T> dans le code ci-dessus.Vous pouvez utiliser cette structure prête à l'emploi de la même manière, si vous le souhaitez.

En C# avec Linq, vous pouvez faire ceci :

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

;)

Essaye celui-là:

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

Je ne suis pas sûr de ce que tu veux dire par :

Je voudrais diviser le tableau d'octets à un certain point (index) sans avoir à simplement créer un nouveau tableau d'octets et copier chaque octet à la fois, augmentant ainsi l'empreinte mémoire de l'opération.

Dans la plupart des langages, certainement en C#, une fois qu'un tableau a été alloué, il n'y a aucun moyen d'en modifier la taille.Il semble que vous cherchiez un moyen de modifier la longueur d'un tableau, ce que vous ne pouvez pas.Vous souhaitez également recycler d'une manière ou d'une autre la mémoire de la deuxième partie du tableau, pour créer un deuxième tableau, ce que vous ne pouvez pas non plus faire.

En résumé:créez simplement un nouveau tableau.

Comme Eren a dit, vous pouvez utiliser ArraySegment<T>.Voici une méthode d'extension et un exemple d'utilisation :

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

Vous ne pouvez pas.Ce que vous souhaiterez peut-être, c'est conserver un point de départ et un nombre d'éléments ;en substance, créez des itérateurs.Si c'est du C++, vous pouvez simplement utiliser std::vector<int> et utilisez ceux intégrés.

En C#, je construirais une petite classe d'itérateur qui contient l'index de départ, le nombre et implémente IEnumerable<>.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top