Read ()

Da Gambas-it.org - Wikipedia.

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, 16)
  
  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


Un'altra modalità, per ottenere il medesimo risultato, può essere la seguente, nella quale in particolare 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 sterna di C "read".

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:
  Repeat
' 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:
    l = read_c(fl.Handle, p + i, SizeOf(gb.Byte))
    Inc i
' Realloca l'area di memoria incrementandola di 1 byte:
    p = Realloc(p, SizeOf(gb.Byte), i)
' Se si è giunti alla fine del file, esce dal ciclo:
  Until l = 0 
   
' Dereferenzia la variabile di tipo Puntatore, per scrivere in console i dati letti dal file:
  Print String@(p)
   
' Libera tutta la memoria precedentemente occupata:
  Free(p)
  fl.Close
  
End



Riferimenti