Frage

Ich habe ein Byte-Array im Speicher, das aus einer Datei gelesen wird.Ich möchte das Byte-Array an einem bestimmten Punkt (Index) aufteilen, ohne einfach ein neues Byte-Array erstellen und jedes Byte einzeln kopieren zu müssen, was den Speicherbedarf des Vorgangs erhöht.Was ich gerne hätte, wäre so etwas:

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

smallPortion würde gleich 1,2,3,4 sein
largeBytes würde 5,6,7,8,9 betragen

War es hilfreich?

Lösung

So würde ich das machen:

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

Andere Tipps

Zu Ihrer Information. System.ArraySegment<T> Struktur ist im Grunde dasselbe wie ArrayView<T> im Code oben.Sie können diese sofort einsatzbereite Struktur auf die gleiche Weise verwenden, wenn Sie möchten.

In C# mit Linq können Sie Folgendes tun:

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

;)

Probier diese:

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

Ich bin mir nicht sicher, was du meinst mit:

Ich möchte das Byte-Array an einem bestimmten Punkt (Index) teilen, ohne einfach ein neues Byte-Array erstellen und jedes Byte einzeln kopieren zu müssen, wodurch der Speicherbedarf des Vorgangs erhöht wird.

In den meisten Sprachen, insbesondere in C#, gibt es keine Möglichkeit, die Größe eines Arrays zu ändern, sobald es zugewiesen wurde.Es hört sich so an, als ob Sie nach einer Möglichkeit suchen, die Länge eines Arrays zu ändern, was nicht möglich ist.Außerdem möchten Sie den Speicher für den zweiten Teil des Arrays irgendwie recyceln, um ein zweites Array zu erstellen, was auch nicht möglich ist.

In Summe:Erstellen Sie einfach ein neues Array.

Als sagte Eren, können Sie verwenden ArraySegment<T>.Hier ist eine Erweiterungsmethode und ein Anwendungsbeispiel:

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

Das kannst du nicht.Möglicherweise möchten Sie einen Ausgangspunkt und eine Anzahl der Elemente beibehalten.im Wesentlichen Iteratoren erstellen.Wenn es sich um C++ handelt, können Sie es einfach verwenden std::vector<int> und verwenden Sie die integrierten.

In C# würde ich eine kleine Iteratorklasse erstellen, die den Startindex, die Anzahl und Implementierungen enthält IEnumerable<>.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top