Differenze tra le versioni di "Read ()"

Da Gambas-it.org - Wikipedia.
 
(17 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
La funzione '''''read( )''''', dichiarata nel file header "''/usr/include/unistd.h''"
+
La funzione '''read()''', dichiarata nel file header "''/usr/include/unistd.h''"
 
  ssize_t read (int __fd, void *__buf, size_t __nbytes)
 
  ssize_t read (int __fd, void *__buf, size_t __nbytes)
 
legge da un file usando il suo file descriptor (1° parametro) un numero di byte definito nel suo 3° parametro, memorizzandoli nel buffer stabilito nel 2° parametro.
 
legge da un file usando il suo file descriptor (1° parametro) un numero di byte definito nel suo 3° parametro, memorizzandoli nel buffer stabilito nel 2° parametro.
Riga 7: Riga 7:
 
<BR>Dunque avremo ad esempio:
 
<BR>Dunque avremo ad esempio:
 
  Private <FONT color=#B22222>Extern read_C</font>(_fd As Integer, __buf As Pointer, __nbytes As Long) As Long In "<FONT color=#B22222>libc:6"</font> <FONT color=#B22222>'''Exec "read"'''</font>
 
  Private <FONT color=#B22222>Extern read_C</font>(_fd As Integer, __buf As Pointer, __nbytes As Long) As Long In "<FONT color=#B22222>libc:6"</font> <FONT color=#B22222>'''Exec "read"'''</font>
 
+
Mostriamo un semplice esempio pratico, nel quale il programma leggerà quanto scritto nella console/Terminale dall'utente:
 
+
Library "libc:6"
Mostriamo un semplice esempio pratico, nel quale il programma leggerà quanto scritto nel Terminale dall'utente:
+
 
  Private const STDIN as integer = 0
 
  Private const STDIN as integer = 0
 +
 +
<FONT Color=gray>' ''ssize_t read (int __fd, void *__buf, size_t __nbytes)''
 +
' ''Read NBYTES into BUF from FD.''</font>
 +
Private Extern <FONT color=#B22222>read_C</font>(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"
 
   
 
   
 
   
 
   
 +
Public Sub Main()
 +
 
 +
  Dim bb As New Byte[16]
 +
 
 +
  <FONT color=#B22222>read_C</font>(STDIN, bb.Data, bb.Count)
 +
 
 +
  Print String@(bb.Data)
 +
 
 +
<FONT Color=gray>' ''....oppure (nel 2° argomento del Metodo ".ToString()" è necessario individuare la posizione del primo elemento del vettore, contenente il valore zero (&h00), affinché la stampa dei caratteri, contenuti dal vettore, si fermi all'ultimo carattere diverso da zero):''</font>
 +
  Print bb.ToString(0, bb.Find(0))
 +
 
 +
End
 +
 +
Quest'altro codice prevede l'uso di un'area di memoria allocata, puntata da una variabile di tipo ''Puntatore'', ove memorizzare i dati (caratteri) scritti nella console/terminale:
 
  Library "libc:6"
 
  Library "libc:6"
 
   
 
   
Riga 20: Riga 38:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
   Dim bb As New Byte[16]
+
   Dim p As Pointer
 +
  Dim st As Stream
 +
  Dim i As Integer
 +
 
 +
  p = Alloc(SizeOf(gb.Byte), 32)
 +
 
 +
<FONT Color=gray>' ''Ripuliamo l'area di memoria allocata, scrivendoci valori uguali a zero (&h00).''
 +
' ''Ciò al fine di consentire alla successiva funzione di dereferenziazione di arrestarsi al primo valore zero incontrato:''</font>
 +
  st = Memory p For Write
 +
  For i = 0 To 32
 +
    Write #st, 0 As Byte
 +
  Next
 +
  st.Close
 +
 
 +
<FONT Color=gray>' ''Nel primo argomento passiamo l'identificativo del "file-descriptor", ottenuto in altro modo:''</font>
 +
  <FONT color=#B22222>read_C</font>(File.In.Handle, p, 32)
 +
 
 +
  Write String@(p)
 
    
 
    
  <FONT color=#B22222>read_C</font>(STDIN, bb.Data, 16)
+
   Free(p)
    
 
  Print String@(bb.Data)
 
 
    
 
    
  '''End'''
+
  End
  
 
+
In questo codice, invece, si aprirà il file-device dello standard input mediante la ordinaria istruzione ''Open'' nativa di Gambas.
Un'altra modalità, per ottenere il medesimo risultato, può essere la seguente:
 
 
   Library "libc:6"
 
   Library "libc:6"
 
   
 
   
Riga 39: Riga 71:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
    
 
    
 
   Dim fl As File
 
   Dim fl As File
Riga 45: Riga 77:
 
   Dim bb As Byte[]
 
   Dim bb As Byte[]
 
    
 
    
  fl = Open "/dev/stdin" For Input
+
<FONT Color=gray>' ''Per permettere che la funzione esterna "read_C" resti in attesa dell'immissione ed invio di uno o più caratteri, è necessario utilizzare l'istruzione "'''For Input'''" (e non "For Read", nel qual caso non vi sarà attesa).''</font>
 +
  fl = Open "/dev/stdin" For <FONT color=#B22222><B>Input</b></font>
 
    
 
    
  bb = New Byte[16]
+
  bb = New Byte[16]
 
    
 
    
  sz = read_C(fl.Handle, bb.Data, 16)
+
  sz = <FONT color=#B22222>read_C</font>(fl.Handle, bb.Data, bb.Count)
 
    
 
    
  Print
+
  Print
  Print bb.ToString(0, sz - 1)
+
<FONT Color=gray>' ''Mostriamo tre modalità possibili in questo caso per stampare in console il risultato:''</font>
 +
  Print bb.ToString(0, CInt(sz - 1)), String@(bb.Data), bb.ToString(0, bb.Find(0))
 
    
 
    
  fl.Close
+
  fl.Close
 
    
 
    
  '''End'''
+
  End
 +
Questo codice mostra come debba essere combinata l'istruzione ''Open'' nativa di Gambas con la funzione esterna "read()" di C.
  
 +
Da notare che se la dimensione del testo immesso è inferiore al valore espresso nel 3° parametro della funzione esterna "''read_C'' ", verrà aggiunto anche il carattere &h0A (nuova riga a capo).
 +
 +
In quest'altro esempio leggeremo il contenuto presente in un file, e scriveremo i dati - ivi letti ad uno ad uno - all'interno di un'area di memoria allocata con la funzione nativa  "Alloc()", la quale andrà dinamicamente aumentando di volta in volta per memorizzare un dato appena letto dal file.
 +
Library "libc:6"
 +
 +
<FONT Color=gray>' ''ssize_t read (int __fd, void *__buf, size_t __nbytes)''
 +
' ''Read NBYTES into BUF from FD.''</font>
 +
Private Extern <Font color=#B22222>read_c</font>(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"
 +
 +
 +
Public Sub Main()
 +
 
 +
  Dim fl As File
 +
  Dim l As Long
 +
  Dim p As Pointer
 +
  Dim i As Integer
 +
 
 +
<FONT Color=gray>' ''Apre il file in "lettura":''</font>
 +
  fl = Open "<FONT Color=darkgreen>''/percorso/del/file''</font>" For Read
 +
 
 +
<FONT Color=gray>' ''Alloca un iniziale byte dell'area di memoria ove scrivere i dati dal file:''</font>
 +
  p = Alloc(SizeOf(gb.Byte), 1)
 +
 
 +
<FONT Color=gray>' ''Inizia il ciclo per leggere dal file un byte di dati alla volta.''
 +
' ''Alla funzione "read_c" viene passato:''
 +
' ''* il numero identificativo del "file-descriptor" del file aperto;''
 +
' ''* la variabile di tipo Puntatore aumentata del valore presente in "i" per spostarci lungo l'area di memoria allocata, al fine di scrivere nel byte disponibile il dato letto dal file'';
 +
' ''* la quantità (pari a 1) di dati da leggere dal file:''</font>
 +
  While <Font color=#B22222>read_c</font>(fl.Handle, p + i, SizeOf(gb.Byte)) > 0
 +
    Inc i
 +
<FONT Color=gray>' ''Realloca l'area di memoria incrementandola di 1 byte:''</font>
 +
    p = Realloc(p, SizeOf(gb.Byte), i + 1)
 +
<FONT Color=gray>' ''Se si è giunti alla fine del file, esce dal ciclo:''</font>
 +
  Wend
 +
   
 +
<FONT Color=gray>' ''Dereferenzia la variabile di tipo Puntatore, per scrivere in console i dati letti dal file.''
 +
' ''Usiamo la funzione "Left()", per prendere soltanto i dati effettivamente letti dal file e memorizzati nell'area di memoria allocata:''</font>
 +
  Print Left(String@(p), i)
 +
   
 +
<FONT Color=gray>' ''Libera tutta la memoria precedentemente occupata:''</font>
 +
  Free(p)
 +
  fl.Close
 +
 
 +
End
 +
Anche in quest'ultimo codice viene mostrato un caso in cui viene combinata l'istruzione ''Open'' nativa di Gambas con la funzione esterna "read()" di C.
  
  

Versione attuale delle 14:01, 13 giu 2024

La funzione read(), dichiarata nel file header "/usr/include/unistd.h"

ssize_t read (int __fd, void *__buf, size_t __nbytes)

legge da un file usando il suo file descriptor (1° parametro) un numero di byte definito nel suo 3° parametro, memorizzandoli nel buffer stabilito nel 2° parametro.


Volendola utilizzare in Gambas, bisognerà dichiararla con Extern, nonché dichiarare la libreria di C: libc.so.6, nella quale la funzione è contenuta. Da sottolineare che, poiché questa funzione esterna di C "read( )" è omonima alla funzione di Gambas "Read", bisognerà assegnarle un nome a piacere, ma si dovrà anche richiamare il suo vero nome con il comando Exec.
Dunque avremo ad esempio:

Private Extern read_C(_fd As Integer, __buf As Pointer, __nbytes As Long) As Long In "libc:6" Exec "read"

Mostriamo un semplice esempio pratico, nel quale il programma leggerà quanto scritto nella console/Terminale dall'utente:

Library "libc:6"

Private const STDIN as integer = 0

' ssize_t read (int __fd, void *__buf, size_t __nbytes)
' Read NBYTES into BUF from FD.
Private Extern read_C(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"


Public Sub Main()
 
 Dim bb As New Byte[16]
 
 read_C(STDIN, bb.Data, bb.Count)
  
 Print String@(bb.Data)
  
' ....oppure (nel 2° argomento del Metodo ".ToString()" è necessario individuare la posizione del primo elemento del vettore, contenente il valore zero (&h00), affinché la stampa dei caratteri, contenuti dal vettore, si fermi all'ultimo carattere diverso da zero):
 Print bb.ToString(0, bb.Find(0))
  
End

Quest'altro codice prevede l'uso di un'area di memoria allocata, puntata da una variabile di tipo Puntatore, ove memorizzare i dati (caratteri) scritti nella console/terminale:

Library "libc:6"

' ssize_t read (int __fd, void *__buf, size_t __nbytes)
' Read NBYTES into BUF from FD.
Private Extern read_C(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"


Public Sub Main()
 
 Dim p As Pointer
 Dim st As Stream
 Dim i As Integer
  
 p = Alloc(SizeOf(gb.Byte), 32)
  
' Ripuliamo l'area di memoria allocata, scrivendoci valori uguali a zero (&h00).
' Ciò al fine di consentire alla successiva funzione di dereferenziazione di arrestarsi al primo valore zero incontrato:
 st = Memory p For Write
 For i = 0 To 32
   Write #st, 0 As Byte
 Next
 st.Close
  
' Nel primo argomento passiamo l'identificativo del "file-descriptor", ottenuto in altro modo:
 read_C(File.In.Handle, p, 32)
  
 Write String@(p)
 
 Free(p)
  
End

In questo codice, invece, si aprirà il file-device dello standard input mediante la ordinaria istruzione Open nativa di Gambas.

 Library "libc:6"

' ssize_t read (int __fd, void *__buf, size_t __nbytes)
' Read NBYTES into BUF from FD.
Private Extern read_C(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"


Public Sub Main()
 
 Dim fl As File
 Dim sz As Long
 Dim bb As Byte[]
  
' Per permettere che la funzione esterna "read_C" resti in attesa dell'immissione ed invio di uno o più caratteri, è necessario utilizzare l'istruzione "For Input" (e non "For Read", nel qual caso non vi sarà attesa).
 fl = Open "/dev/stdin" For Input
  
 bb = New Byte[16]
  
 sz = read_C(fl.Handle, bb.Data, bb.Count)
  
 Print
' Mostriamo tre modalità possibili in questo caso per stampare in console il risultato:
 Print bb.ToString(0, CInt(sz - 1)), String@(bb.Data), bb.ToString(0, bb.Find(0))
  
 fl.Close
  
End

Questo codice mostra come debba essere combinata l'istruzione Open nativa di Gambas con la funzione esterna "read()" di C.

Da notare che se la dimensione del testo immesso è inferiore al valore espresso nel 3° parametro della funzione esterna "read_C ", verrà aggiunto anche il carattere &h0A (nuova riga a capo).

In quest'altro esempio leggeremo il contenuto presente in un file, e scriveremo i dati - ivi letti ad uno ad uno - all'interno di un'area di memoria allocata con la funzione nativa "Alloc()", la quale andrà dinamicamente aumentando di volta in volta per memorizzare un dato appena letto dal file.

Library "libc:6"

' ssize_t read (int __fd, void *__buf, size_t __nbytes)
' Read NBYTES into BUF from FD.
Private Extern read_c(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read"


Public Sub Main()
 
 Dim fl As File
 Dim l As Long
 Dim p As Pointer
 Dim i As Integer
  
' Apre il file in "lettura":
 fl = Open "/percorso/del/file" For Read
  
' Alloca un iniziale byte dell'area di memoria ove scrivere i dati dal file:
 p = Alloc(SizeOf(gb.Byte), 1)
  
' Inizia il ciclo per leggere dal file un byte di dati alla volta.
' Alla funzione "read_c" viene passato:
' * il numero identificativo del "file-descriptor" del file aperto;
' * la variabile di tipo Puntatore aumentata del valore presente in "i" per spostarci lungo l'area di memoria allocata, al fine di scrivere nel byte disponibile il dato letto dal file;
' * la quantità (pari a 1) di dati da leggere dal file:
 While read_c(fl.Handle, p + i, SizeOf(gb.Byte)) > 0
   Inc i
' Realloca l'area di memoria incrementandola di 1 byte:
   p = Realloc(p, SizeOf(gb.Byte), i + 1)
' Se si è giunti alla fine del file, esce dal ciclo:
 Wend
   
' Dereferenzia la variabile di tipo Puntatore, per scrivere in console i dati letti dal file.
' Usiamo la funzione "Left()", per prendere soltanto i dati effettivamente letti dal file e memorizzati nell'area di memoria allocata:
 Print Left(String@(p), i)
   
' Libera tutta la memoria precedentemente occupata:
 Free(p)
 fl.Close
  
End

Anche in quest'ultimo codice viene mostrato un caso in cui viene combinata l'istruzione Open nativa di Gambas con la funzione esterna "read()" di C.


Riferimenti