Leggere e scrivere in un vettore mediante i Memory Stream
Per poter leggere i dati da un vettore e/o scrivere dati in un vettore mediante i Memory Stream, è necessario ottenere l'indirizzo di memoria del vettore medesimo. Tale risultato con i vettori, così come anche con le matrici, si ottiene mediante la Proprietà ".Data", la quale ritorna un Puntatore ai dati contenuti dal vettore. [nota 1]
Leggere e scrivere in un vettore di tipo "Byte[]"
Mostriamo dunque un esempio, nel quale si legge e si scrive in un vettore di tipo "Byte[]" mediante i Memory Stream ed usando la proprietà .Data dei vettori:
Public Sub Main()
Dim v As Byte[] = [10, 20, 30, 40]
Dim p As Pointer
Dim st As Stream
Dim b, j As Byte
' Assegna ad un "Puntatore" l'area di memoria del vettore:
p = v.Data
st = Memory p For Read Write
' Aggiunge (scriviamo) subito un valore alla fine del vettore:
Seek #st, 4
' Scrive nel "Puntatore" mediante lo "Stream":
Write #st, 99 As Byte
' Legge nell'indirizzo di memoria del vettore:
For j = 0 To v.Count
Seek #st, j
Read #st, b
Print b
Next
' Sostituisce (scrive) un valore nel 3° elemento del vettore:
Seek #st, 2
Write #st, 88 As Byte
' Legge nell'indirizzo di memoria del vettore come definitivamente modificato:
For j = 0 To v.Count
Seek #st, j
Read #st, b
Print b
Next
st.Close
End
Stesso esempio, ma con vettore di tipo "Short[]"
Ovviamente valori di tipo Short occupano ciascuno 2 byte, quindi:
Public Sub Main()
Dim v As Short[] = [10, 20, 30, 40]
Dim p As Pointer
Dim st As Stream
Dim j As Byte
Dim sh As Short
' Assegna ad un "Puntatore" l'area di memoria del vettore:
p = v.Data
st = Memory p For Read Write
' Aggiunge (scrive) subito un valore alla fine del vettore:
Seek #st, 4 * SizeOf(gb.Short)
' Scrive nel "Puntatore" mediante lo "Stream":
Write #st, 99 As Byte
' Legge nell'indirizzo di memoria del vettore:
For j = 0 To v.Count * SizeOf(gb.Short) Step 2
Seek #st, j
Read #st, sh
Print sh
Next
' Sostituisce (scrive) un valore nel 3° elemento del vettore:
Seek #st, 2 * SizeOf(gb.Short)
Write #st, 88 As Byte
' Legge nell'indirizzo di memoria del vettore come definitivamente modificato:
For j = 0 To v.Count * SizeOf(gb.Short) Step 2
Seek #st, j
Read #st, sh
Print sh
Next
st.Close
End
Stesso esempio, ma con vettore di tipo "Integer[]"
Ovviamente valori di tipo Integer occupano ciascuno 4 byte, quindi:
Public Sub Main()
Dim v As Integer[] = [10, 20, 30, 40]
Dim p As Pointer
Dim st As Stream
Dim j As Byte
Dim i As Integer
' Assegna ad un "Puntatore" l'area di memoria del vettore:
p = v.Data
st = Memory p For Read Write
' Aggiunge (scrive) subito un valore alla fine del vettore:
Seek #st, 4 * SizeOf(gb.Integer)
' Scrive nel "Puntatore" mediante lo "Stream":
Write #st, 99 As Integer
' Legge nell'indirizzo di memoria del vettore:
For j = 0 To v.Count * SizeOf(gb.Integer) Step 4
Seek #st, j
Read #st, i
Print i
Next
' Sostituisce (scrive) un valore nel 3° elemento del vettore:
Seek #st, 2 * SizeOf(gb.Integer)
Write #st, 88 As Integer
' Legge nell'indirizzo di memoria del vettore come definitivamente modificato:
For j = 0 To v.Count * SizeOf(gb.Integer) Step 4
Seek #st, j
Read #st, i
Print i
Next
st.Close
End
...e così via con gli altri tipi di variabili.
Leggere e scrivere in un vettore multidimensionale con numero determinato di elementi
Nel caso di lettura o scrittura con un vettore multidimensionale con numero determinato di elementi
Dim matrice As New Byte[n, n]
o annidato
Private matrice[n, n] As Byte
i dati iniziano dall'indice zero seguendo l'ordine delle colonne.
Esempio:
Public Sub Main() Dim bb As New Byte[3, 3] Dim p As Pointer Dim st As Stream Dim j, b As Byte bb[0, 0] = 99 bb[0, 1] = 99 bb[0, 2] = 99 bb[1, 0] = 111 bb[1, 1] = 111 bb[1, 2] = 111 ' Assegna ad un "Puntatore" l'area di memoria del vettore: p = bb.Data st = Memory p For Read For j = 0 To 5 Read #st, b Print j, b Next st.Close() End
Leggere e scrivere in un vettore multidimensionale con numero non determinato di elementi
Nel caso di lettura o scrittura in un vettore multidimensionale con numero non determinato di elementi
Dim bb As New Byte[][]
i dati del primo vettore hanno inizio dall'indice 256.
I dati da un vettore all'altro si distanziano di 144 byte. Pertanto, in un tipo di vettore di questo genere, formato ad esempio da tre elementi-vettori, il primo dato del primo elemento-vettore si troverà all'indice 256; il primo dato del secondo elemento-vettore si troverà all'indice 400; il primo dato del terzo elemento-vettore si troverà all'indice 544.
Esempio:
Private Const PRIMO_VALORE As Short = 256
Private Const INTERVALLO As Byte = 144
Public Sub Main()
Dim bb As New Byte[][]
Dim st As Stream
Dim j, b As Byte
bb = [[11, 11], [99, 99], [100, 100], [200, 200]]
st = Memory bb.Data For Read
Wait 0.01
For c As Short = PRIMO_VALORE To PRIMO_VALORE + (INTERVALLO * bb.Max) Step INTERVALLO
Seek #st, c
Wait 0.01
For n As Byte = 0 To bb[j].Max
Read #st, b
Print c, b
Next
Inc j
Next
st.Close()
End
Nei vettori multidimensionali con numero non determinato di elementi di terzo livello i dati hanno una distanza dei byte fra un elemento-vettore e l'altro del medesimo livello pari a 144 byte. La distanza del primo dato di un nuovo livello dal primo dato del precedente livello è pari a 400 byte.
Mostriamo come pura curiosità un codice adattato all'esempio di vettore a tre dimensioni ivi riportato:
Private LIVELLI As Integer
Private Const SALTO_NEL_LIVELLO As Byte = 144
Private Const SALTO_LIVELLI As Short = 400
Public Sub Main()
Dim bb As New Byte[][][]
Dim st As Stream
Dim c, d As Short
Dim t, b As Byte
bb = [[[1, 2, 3, 4], [11, 12, 13, 14]], [[110, 120, 130, 140], [200, 210, 220, 230]]]
' Individua il byte del primo valore contenuto dal primo elemento-vettore del terzo livello:
Repeat
Inc LIVELLI
Until (Byte@(bb.Data + LIVELLI) == 1) And (Byte@((bb.Data + LIVELLI) + 1) == 2) And (Byte@((bb.Data + LIVELLI) + 2) == 3) And (Byte@((bb.Data + LIVELLI) + 3) == 4)
st = Memory bb.Data For Read
Seek #st, LIVELLI
Write "\e[34m[\e[0m"
Repeat
Write "\e[33m[\e[0m"
Repeat
LIVELLI += d
Seek #st, LIVELLI
Write "\e[32m[\e[0m"
For t = 0 To bb[0][0].Max
Read #st, b
Print b;;
Next
d += SALTO_NEL_LIVELLO
Write "\e[32m]\e[0m"
Until d == SALTO_NEL_LIVELLO * bb[0].Count
LIVELLI += SALTO_LIVELLI
d = 0
Inc c
Write "\e[33m]\e[0m"
Until c == bb.Count
Write "\e[34m]\e[0m"
st.Close()
End
Note
[1] Vedasi anche la seguente pagina della WIKI: Assegnare ad un vettore i valori contenuti da un'area di memoria puntata da un Puntatore