Differenze tra le versioni di "Definizione ed uso dei Memory Stream"

Da Gambas-it.org - Wikipedia.
Riga 3: Riga 3:
 
In sostanza la classe ''Memory-Stream'' serve per leggere e per scrivere in una variabile di tipo ''Puntatore'' che punta ad un'<I>area di memoria riservata</i>.
 
In sostanza la classe ''Memory-Stream'' serve per leggere e per scrivere in una variabile di tipo ''Puntatore'' che punta ad un'<I>area di memoria riservata</i>.
  
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()''; oppure può essere un'area di memoria avente una dimensione allocata da noi mediante la funzione ''Alloc()''.
+
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:
 
La sintassi dell'utilizzo dei ''Memory Stream'' è la seguente:
  Flusso = MEMORY ''Puntatore'' FOR [ READ ] [ WRITE ]
+
  variabile_Stream = MEMORY ''Puntatore'' FOR [ READ ] [ WRITE ]
  
 
* Se la parola chiave ''READ'' viene specificata, allora è permessa la lettura.
 
* Se la parola chiave ''READ'' viene specificata, allora è permessa la lettura.
Riga 13: Riga 18:
  
 
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.
 
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'' .
  
  
Riga 18: Riga 25:
 
La modalità in "Scrittura" (''For Write'') risulta utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata. Si può quindi scrivere nella variabile ''Stream'' con l'istruzione "''Write''" o anche con l'istruzione "''Print''".
 
La modalità in "Scrittura" (''For Write'') risulta utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata. Si può quindi scrivere nella variabile ''Stream'' con l'istruzione "''Write''" o anche con l'istruzione "''Print''".
  
Per esempio, se si intende creare una sequenza di byte &h80, &h81, &h82, &h83, lo si può fare con i chr(); oppure si può scrivere:
+
Riteniamo utile fare un semplice confronto con il codice C:
 +
'''Public''' Sub Main()
 +
 +
  Dim i As Integer              <Font Color=#B22222>' ''  int i;''</font>
 +
  Dim p As Pointer              <Font Color=#B22222>' ''  int * p;''</font>
 +
  Dim st As Stream
 +
 +
<Font Color=gray>' ''Si dereferenzia il Puntatore, ossia si accede alla locazione di memoria puntata (quella della variabile "i"):''</font>
 +
  p = VarPtr(i)                <Font Color=#B22222>' ''  p = &i;''</font>
 +
 
 +
<Font Color=gray>' ''Si scrive (in Gambas lo si fa usando una variabile di tipo "Stream") nella locazione di memoria puntata (quella della variabile "i"):''</font>
 +
  st = Memory p For Write
 +
  Write #st, 99999 As Integer  <Font Color=#B22222>' ''  *p = 99999''</font>
 +
  st.Close
 +
   
 +
  Print "i =  "; i              <Font Color=#B22222>' ''  printf("i =  %d\n", i);''</font>
 +
 +
'''End'''
 +
 
 +
 
 +
In quest'altro esempio, si intende creare all'interno di un'area di memoria riservata una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:
 
  '''Private''' sWR As Stream
 
  '''Private''' sWR As Stream
 
   
 
   
Riga 27: Riga 54:
 
   Dim b As Byte
 
   Dim b As Byte
 
   
 
   
  <Font Color= #006400>' ''Riserviamo 4 byte da qualche parte in memoria:''</font>
+
  <Font Color=gray>' ''Riserviamo 4 byte da qualche parte in memoria:''</font>
 
   p = Alloc(4)
 
   p = Alloc(4)
 
   
 
   
  <Font Color= #006400>' ''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>
 
   sWR = Memory p For Write
 
   sWR = Memory p For Write
 
   
 
   
  <Font Color= #006400>' ''...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 bWr = 80 to 83
 
   For bWr = 80 to 83
Riga 39: Riga 66:
 
   Next
 
   Next
 
   
 
   
  <Font Color= #006400>' ''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>
 
   sWr.Close
 
   sWr.Close
 
   Free(p)
 
   Free(p)
Riga 55: Riga 82:
 
   
 
   
 
  Dim j, b As Byte
 
  Dim j, b As Byte
 +
 +
<Font Color=gray>' ''Reimpostiamo la lettura dello "stream" dall'indice 0:''</font>
 +
    Seek #sWR, j
 
   
 
   
 
   For j = 0 To 3
 
   For j = 0 To 3
<Font Color= #006400>' ''Reimpostiamo la lettura dello "stream" dall'indice 0:''</font>
 
    Seek #sWR, j
 
 
     Read #sWR, b
 
     Read #sWR, b
 
   
 
   
  <Font Color= #006400>' ''A fini didattici, mostriamo il valore in console''</font>
+
  <Font Color=gray>' ''A fini didattici, mostriamo il valore in console''</font>
 
     Print "---> ", b
 
     Print "---> ", b
 
   Next
 
   Next
 
   
 
   
  <Font Color= #006400>' ''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>
 
   sWR.Close
 
   sWR.Close
 
   Free(p)
 
   Free(p)

Versione delle 10:28, 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"

La modalità in "Scrittura" (For Write) risulta utile nel caso si debbano scrivere dei valori all'interno di un'area di memoria riservata, allocata. 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


In quest'altro esempio, si intende creare all'interno di un'area di memoria riservata una sequenza dei seguenti byte: &h80, &h81, &h82, &h83, lo si può fare scrivendo:

Private sWR 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...
  sWR = 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 bWr = 80 to 83
    Write #sWR, b As Byte
  Next

' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
  sWr.Close
  Free(p)

End


Memory Stream in modalità "For Read"

In modalità "For Read" i Memory-Stream possono essere usati per dereferenziare i puntatori.

Riprendiamo l'esempio del precedente paragrafo, relativo alla modalità in "scrittura" dei Memory-Stream. Lì abbiamo visto che quattro valori numerici sono stati memorizzati in un area riservata, pumtata dalla variabile puntatore "p".

Ora procediamo a dereferenziare quella variabile di tipo pointer, e ad estrarre i valori contenuti nell'aera riservata di memoria:

Public Sub Button2_Click()

Dim j, b As Byte

' Reimpostiamo la lettura dello "stream" dall'indice 0:
   Seek #sWR, j

 For j = 0 To 3
   Read #sWR, b

' A fini didattici, mostriamo il valore in console
   Print "---> ", b
 Next

' Chiudiamo il flusso e liberiamo la parte di memoria precedentemente allocata:
 sWR.Close
 Free(p)

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