Definizione ed uso dei Memory Stream: differenze tra le versioni
Nessun oggetto della modifica |
Nessun oggetto della modifica |
||
| Riga 23: | Riga 23: | ||
==Memory Stream in modalità "For Write"== | ==Memory Stream in modalità "For Write"== | ||
Si può quindi scrivere nella variabile ''Stream'' con l'istruzione "''Write''" o anche con l'istruzione "''Print''". | |||
Riteniamo utile fare un semplice confronto con il codice C: | Riteniamo utile fare un semplice confronto con il codice C: | ||
| Riga 45: | Riga 45: | ||
In | Ma la modalità in "Scrittura" (''For Write'') risulta ''particolarmente'' utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata con la funzione ''Alloc()'' . | ||
'''Private''' | |||
In questo esempio, si intende creare all'interno di un'area di memoria riservata con ''Alloc()'' una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo: | |||
'''Private''' st As Stream | |||
| Riga 58: | Riga 60: | ||
<Font Color=gray>' ''Questa memoria sarà un flusso (stream) che creeremo appositamente, e...''</font> | <Font Color=gray>' ''Questa memoria sarà un flusso (stream) che creeremo appositamente, e...''</font> | ||
st = Memory p For Write | |||
<Font Color=gray>' ''...nel quale andiamo a scrivere i 4 valori byte.'' | <Font Color=gray>' ''...nel quale andiamo a scrivere i 4 valori byte.'' | ||
' ''Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:''</font> | ' ''Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:''</font> | ||
For | For b = 80 to 83 | ||
Write # | Write #st, b As Byte | ||
Next | Next | ||
<Font Color=gray>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font> | <Font Color=gray>' ''Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:''</font> | ||
st.Close | |||
Free(p) | Free(p) | ||
| Riga 76: | Riga 78: | ||
In modalità "''For Read''" i Memory-Stream possono essere usati per [[Variabili_di_tipo_Puntatore_e_loro_dereferenziazione|dereferenziare i puntatori]]. | In modalità "''For Read''" i Memory-Stream possono essere usati per [[Variabili_di_tipo_Puntatore_e_loro_dereferenziazione|dereferenziare i puntatori]]. | ||
Per mostrare un esempio pratico, poniamo il caso che ad una sub-procedura venga passato un ''Puntatore'', che punta ad un'area riservata precedentemente allocata (come nell'esempio visto nel paragrafo di sopra) al fine di derefenziarlo con i ''Memory Stream''. Si procederà ad estrarre i valori contenuti in quest'aera riservata di memoria: | |||
'''Public''' Procedure Dereferenzia(p As Pointer) | |||
'''Public''' | |||
Dim j, b As Byte | |||
Dim st As Stream | |||
<Font Color=gray>' ''Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:''</font> | |||
st As Stream | |||
<Font Color=gray>' '' | <Font Color=gray>' ''Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":''</font> | ||
For j = 0 To 3 | |||
Read #st, b | |||
Print "---> ", b | |||
Next | |||
<Font Color=gray>' ''Chiudiamo il flusso | <Font Color=gray>' ''Chiudiamo il flusso:''</font> | ||
st.Close | |||
'''End''' | '''End''' | ||
Versione delle 10:40, 8 nov 2014
La classe Memory-Stream crea flussi di dati che utilizzano la RAM. Pertanto, i "Memory-Stream" sono dei flussi di dati in memoria.
In sostanza la classe Memory-Stream serve per leggere e per scrivere in una variabile di tipo Puntatore che punta ad un'area di memoria riservata.
Tale area di memoria può essere:
- quella di una variabile, dalla quale sarà stato creato un Puntatore (che punta all'indirizzo di detta variabile) con la funzione VarPtr();
- un'area riservata avente una determinata dimensione allocata da noi mediante la funzione Alloc();
- quella di un Puntatore passato da una funzione esterna dichiarata con Extern.
Una volta utilizzata
La scrittura e la lettura avviene utilizzando una variabile di tipo "Stream" generata dalla risorsa Memory-Stream partendo dalla variabile Puntatore.
La sintassi dell'utilizzo dei Memory Stream è la seguente:
variabile_Stream = MEMORY Puntatore FOR [ READ ] [ WRITE ]
- Se la parola chiave READ viene specificata, allora è permessa la lettura.
- Se la parola chiave WRITE viene specificata, allora è permessa la scrittura.
Ovviamente, con riferimento al formato Big-Endian/Little-Endian, la procedura di scrittura e di lettura dei dati nel flusso (stream) è identica alla procedura che avviene con i file.
Una volta utilizzata per leggere o per scrivere nel Puntatore, la variabile di tipo Stream viene abbandonata chiudendo il flusso con il metodo variabile_Stream.Close .
Memory Stream in modalità "For Write"
Si può quindi scrivere nella variabile Stream con l'istruzione "Write" o anche con l'istruzione "Print".
Riteniamo utile fare un semplice confronto con il codice C:
Public Sub Main()
Dim i As Integer ' int i;
Dim p As Pointer ' int * p;
Dim st As Stream
' Si dereferenzia il Puntatore, ossia si accede alla locazione di memoria puntata (quella della variabile "i"):
p = VarPtr(i) ' p = &i;
' Si scrive (in Gambas lo si fa usando una variabile di tipo "Stream") nella locazione di memoria puntata (quella della variabile "i"):
st = Memory p For Write
Write #st, 99999 As Integer ' *p = 99999
st.Close
Print "i = "; i ' printf("i = %d\n", i);
End
Ma la modalità in "Scrittura" (For Write) risulta particolarmente utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata con la funzione Alloc() .
In questo esempio, si intende creare all'interno di un'area di memoria riservata con Alloc() una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:
Private st As Stream
Public Sub Button1_Click()
Dim p As Pointer
Dim b As Byte
' Riserviamo 4 byte da qualche parte in memoria:
p = Alloc(4)
' Questa memoria sarà un flusso (stream) che creeremo appositamente, e...
st = Memory p For Write
' ...nel quale andiamo a scrivere i 4 valori byte.
' Ogni valore byte occuperà la dimensione di 1 byte, quindi copriranno esattamente i 4 byte allocati:
For b = 80 to 83
Write #st, b As Byte
Next
' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
st.Close
Free(p)
End
Memory Stream in modalità "For Read"
In modalità "For Read" i Memory-Stream possono essere usati per dereferenziare i puntatori.
Per mostrare un esempio pratico, poniamo il caso che ad una sub-procedura venga passato un Puntatore, che punta ad un'area riservata precedentemente allocata (come nell'esempio visto nel paragrafo di sopra) al fine di derefenziarlo con i Memory Stream. Si procederà ad estrarre i valori contenuti in quest'aera riservata di memoria:
Public Procedure Dereferenzia(p As Pointer)
Dim j, b As Byte
Dim st As Stream
' Generiamo la variabile di tipo "Stream" dal "Puntatore" che è stato passato con la chiamata della sub-procedura:
st As Stream
' Riprendiamo l'esempio del paragrafo precedente, dove sono stati scritti 4 valori di tipo "byte"; e li andiamo ad "estrarre" leggendo dalla variabile di tipo "Stream":
For j = 0 To 3
Read #st, b
Print "---> ", b
Next
' Chiudiamo il flusso:
st.Close
End
Altri esempi sulla scrittura e lettura delle variabili di tipo "Stream"
Scriviamo nello Stream un testo, poi lo recuperiamo leggendo lo Stream:
Public Sub Button1_Click()
Dim p As Pointer
Dim st As Stream
Dim s, ss As String
Dim j As Byte
p = Alloc(4)
st = Memory p For Read Write
s = "testo qualsiasi"
' Scriviamo la stringa nella variabile di tipo "Stream":
Print #st, s
'''''''''''''''
' Leggiamo nella variabile di tipo "Stream"
' Poiché con la precedente scrittura l'indice dello "stream"
' è incrementato di uno, si dovrà re-impostare la lettura all'indice zero:
Seek #st, 0
Line Input #st, ss
Print "Contenuto dello stream: "; ss
' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
st.Close
Free(p)
End
Secondo esempio - leggiamo con l'istruzione Shell congiunta al comando bash "ls" nella cartella "/proc", e riportiamo in una TextArea il contenuto ivi letto distinguendo ciascuna sub-cartella o file mediante Input.
Nel codice scriveremo in un flusso per mezzo dei Memory Stream tutti i dati ricavati con ls; e per verifica leggeremo dal flusso - sempre per mezzo dei Memory Stream - quei dati scritti poco prima:
Public Sub Button1_Click()
Dim s, ss As String
Dim p As Pointer
Dim m As Stream
Dim j As Integer
Shell "ls /proc" To s
' Allochiamo sufficiente memoria,
' e vi puntiamo con una variabile di tipo "puntatore":
p = Alloc(2048)
' Creiamo la variabile "m" di tipo "Stream":
m = Memory p For Read Write
' Scriviamo nella variabile "m" il contenuto della variabile stringa "s":
Print #m, s
While Not Eof(m)
' Guidiamo la lettura nella variabile "m" mediante il comando "Seek":
Seek #m, j
Input #m, ss
' Se non vi sono più dati relativi a caratteri alfanumerici, allora si esce dal ciclo:
If ss = Null Then Exit
TextArea1.Text &= ss & Chr(10)
' Si dà il valore al comando "Seek per far cominciare"
' la lettura dal byte corrispondente nella variabile "s" ad ogni inizio riga:
j = j + Len(ss) + 1
Wend
' Liberiamo la parte di memoria precedentemente allocata:
m.Close
Free(p)
End
In modalità "Lettura" per dereferenziare i puntatori passati da funzioni esterne
Si procederà ugualmente per dereferenziare i puntatori passati da funzioni esterne.
Public Sub Button1_Click() Dim pEst As Pointer Dim pS As Stream Dim by As Byte ' Prendiamo da una funzione esterna un valore di tipo puntatore: funzione_esterna_che_passa_un puntatore(pEst) ' Usiamo i Memory Stream in modalità di "lettura": pS = Memory pEst For Read 'Andiamo a dereferenziare e, quindi, a leggere il dato: Read #pS, by pS.Close ' Ora, a fini didattici, mostriamo il valore in console: Print by End