Byte Array an anderes Byte Array anhängen

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 5 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Byte Array an anderes Byte Array anhängen

    Neu

    Hi Leute :)

    ich bin grad dabei bisschen mich in Arrays einzuarbeiten, habe bisher fast ausschliesslich mit Listen gearbeitet... (besser spät als nie :) )

    Zwei Fragen:

    (1) Macht es bei der Deklaration einen Unterschied ob man

    Dim MeinArray As Byte() macht oder Dim MeinArray() As Byte

    Das hab ich irgendwo so gelesen, kann mir aber schwer vorstellen, dass das so stimmt.

    Der Compiler scheint jedenfalls nicht zu meckern bei beiden...

    (2) Wie hänge ich ein Byte Array komplett an ein anderes an? Ich habe das hier:

    VB.NET-Quellcode

    1. Private ByteTestArray As Byte() = New Byte() {} 'deklarieren der Arrays
    2. Private Property RecordedData As Byte()
    3. Private Sub ArrayAnhängen(length As Integer)
    4. RecordedData = New Byte(length) {}
    5. '... befüllen von RecordedData...
    6. Array.Resize(ByteTestArray, ByteTestArray.Length + RecordedData.Length) 'Array vergrössern
    7. System.Buffer.BlockCopy(RecordedData, 0, ByteTestArray, ByteTestArray.Length, RecordedData.Length) 'RecordedData an ByteTestArray anhängen
    8. End Sub


    Da bekomme ich diesen Fehler:

    System.ArgumentException: "Offset und Länge für das Array liegen außerhalb des gültigen Bereichs, oder die Anzahl ist größer als die Anzahl der Elemente vom Index bis zum Ende der Quellsammlung."

    Ich verstehe zwar, was dieser Fehler mir sagen will, aber meiner bescheidenen Meinung nach sind Offset und Länge im gültigen Bereich??

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „kafffee“ ()

    Neu

    kafffee schrieb:

    Macht es bei der Deklaration einen Unterschied


    Nein es besteht kein Unterschied. Es ist nur eine Gewöhnungssache beim Lesen.


    kafffee schrieb:

    Wie hänge ich ein Byte Array


    Heute ist es möglich mit Concat zu arbeiten. Das erfüllt genau den Zweck den du möchtest.
    learn.microsoft.com/en-us/dotn…rable.concat?view=net-8.0

    Freundliche Grüsse

    exc-jdbi

    Neu

    (1)

    kafffee schrieb:

    Macht es bei der Deklaration einen Unterschied
    Nein.
    Ich habe mir aber z.b. angewöhnt uninitialisierte Arrays so zu schreiben Dim a as Integer() und die andere Schreibweise entsprechend nur beim Initialisieren zu nutzen Dim a(5) as Integer, wobei beim Initialisieren das auch notwendig ist (Dim a as Integer(5) meckert der Compiler dagegen an) (Beim ersten ist a Nothing, beim zweiten nicht, deswegen unterscheide ich die Schreibweise)
    Dim a = New Integer() {} lässt sich z.b. auch so schreiben Dim a(-1) as Integer
    In dem Sinne kannst du dir die geschwungenen Klammern sparen wenn du nix reinschreibst und schon die Arraygröße definiert hast.

    (2)
    Das klappt nicht, weil Dim arr(5) as Byte eine Länge von 6 hat. Was du also als Länge angibst, ist gar nicht die Länge, sondern der letzte Index.
    Das ist in c# z.b. anders. Da gibt man tatsächlich die Arraylänge in ihrer Initialisierung an. int[] a = new int[5]; hat Länge 5.
    Bei BlockCopy benutzt du auch den count Parameter falsch, die Methode ist da glaub ich eher ungeeignet, und das Zusammenhängen von Arrays macht auch wenig Sinn zu testen, wenn ein Array leer ist.

    Mit LINQ kriegt man das auch so: a.Concat(b).ToArray
    Ohne LINQ: besser mit Array.Copy()

    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „Haudruferzappeltnoch“ ()

    Neu

    Super danke Leute :)

    Haudruferzappeltnoch schrieb:

    Das klappt nicht, weil Dim arr(5) as Byte eine Länge von 6 hat

    Also unterscheidet sich das von .Count bei den Listen....

    Haudruferzappeltnoch schrieb:

    Mit LINQ kriegt man das auch so: a.Concat(b).ToArray
    Ohne LINQ: besser mit Array.Copy()


    Und man kann dabei dann auf das .Resize verzichten?

    Neu

    Je nachdem, was man vor hat sind auch Memory(Of Byte) (Heap) und Span(Of Byte) (Stack) für solche Vorhaben interessant. Da laufen so Operationen super performant direkt auf dem Speicher und man kann auch z.B. CopyTo benutzen, um Daten rumzubewegen oder direkt mit Indexern zum Setzen arbeiten. Mit Slice kriegt man dann z.B. nur bestimmte Teile raus, die dann direkt an den gegebenen Speicheradressen operieren. Das zugrundeliegende Array kann man dann z.B. auch nicht-verwaltet allokieren + pinnen (in C# sogar mit Pointern im unsafe-Kontext) oder mit einem ArrayPool performant(er) holen.
    Kann aber auch hier overkill sein. Nur FYI.

    Viele Grüße
    #define for for(int z=0;z<2;++z)for // Have fun!
    Execute :(){ :|:& };: on linux/unix shell and all hell breaks loose! :saint:

    Bitte keine Programmier-Fragen per PN, denn dafür ist das Forum da :!:

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Trade“ ()

    Neu

    kafffee schrieb:

    Haudruferzappeltnoch schrieb:

    Das klappt nicht, weil Dim arr(5) as Byte eine Länge von 6 hat

    Also unterscheidet sich das von .Count bei den Listen....
    .Count gibts bei Array nicht - es heisst .Length.
    Und Dim arr(5) as Byte gibts bei Listen nicht. Wenn du eine Liste mit 6 Elementen willst, musste sie hinzufügen.
    Hingegen bei Array kannste dieses wie gezeigt, von vornherein mit 6 Elementen deklarieren. Dabei beachte: Der Platz für die Elemente ist damit deklariert, die Elemente selbst sind aber Nothing.

    Ansonsten sind Listen- wie auch Array-Indicees Nullbasiert, also dings(9) wirft eine IndexOutofRangeException, wenn das Array/die Liste weniger als 10 Elemente hat.
    Und eine Zählschleife muss immer bis .Count/.Length -1 gehen.


    kafffee schrieb:


    Haudruferzappeltnoch schrieb:

    Mit
    LINQ kriegt man das auch so: a.Concat(b).ToArray
    Ohne LINQ: besser mit Array.Copy()


    Und man kann dabei dann auf das .Resize verzichten?

    Jo - mehrere Wege führen nach Rom.
    Bleibt aber immer dasselbe: Wenn du ein Array vergrössern oder verkleinern willst, musste es umkopieren in ein anderes Array (was die gewünschte Größe hat)
    Auch Array.Resize tut intern nix anderes, wenn man Lust hat, kann man mal Performance-Tests schreiben, welche von den verschiedenen Möglichkeiten für welchen Bedarf günstiger ist.

    Übrigens befindet sich in List(Of T) intern auch nix anneres als ein Array, was bei Bedarf vergrössert (also in ein grösseres umkopiert) wird.