Differenze tra le versioni di "Leggere il contenuto di una Directory mediante le risorse dichiarate nel file header "dirent.h""

Da Gambas-it.org - Wikipedia.
 
Riga 1: Riga 1:
Come si sa, per leggere i file contenuti in una Directory, in Gambas si utilizza la comoda funzione ''Dir()''.
+
Come si sa, per leggere i file contenuti in una Directory, in Gambas si utilizza la comoda funzione "Dir()".
  
In questa pagina viene mostrato come utilizzare alcune risorse dichiarate nel file header "''usr/include/dirent.h''", per conoscere i file presenti in una Directory.
+
In questa pagina viene mostrato come utilizzare alcune risorse dichiarate nel file header "''usr/include/dirent.h'' ", per conoscere i file presenti in una Directory.
 
 
E' necessario richiamare in Gambas la libreria dinamica condivisa: "''libc:6''"
 
  
 +
E' necessario richiamare in Gambas la libreria condivisa: "''libc.so.6'' ".
  
 
Mostriamo di seguito due codici possibili.
 
Mostriamo di seguito due codici possibili.
Riga 10: Riga 9:
  
 
===1° esempio===
 
===1° esempio===
E' sufficiente richiamare tre funzioni esterne, dichiarate nel file header ''dirent.h''. I dati saranno immagazzinati in un'area di memoria, creata dalla funzione esterna ''readdir()'' e puntata da apposita variabile di tipo ''Puntatore''. Si procederà alla dereferenziazione di detto ''Puntatore'' mediante le apposite funzioni di dereferenziazione previste da Gambas, tenendo comunque tenendo ben presente che:
+
E' sufficiente richiamare tre funzioni esterne, dichiarate nel file header ''dirent.h''. I dati saranno immagazzinati in un'area di memoria, creata dalla funzione esterna "readdir()" e puntata da apposita variabile di tipo ''Puntatore''. Si procederà alla dereferenziazione di detto ''Puntatore'' mediante le apposite funzioni di dereferenziazione previste da Gambas, tenendo comunque tenendo ben presente che:
<BR>- i dati utili per la lettura della Dirctory iniziano dal byte di indice <FONT Color=#B22222>64</font> dell'area di memoria puntata dal ''Puntatore'';
+
<BR>- i dati utili per la lettura della Dirctory iniziano dal byte di indice <FONT Color=#B22222>16</font> dell'area di memoria puntata dal ''Puntatore'';
 
<BR>- l'area di memoria utile è suddivisa in varie porzioni contenenti - quali dati utili alla conoscenza dei file presenti nella Directory - il tipo di file ed il suo nome;
 
<BR>- l'area di memoria utile è suddivisa in varie porzioni contenenti - quali dati utili alla conoscenza dei file presenti nella Directory - il tipo di file ed il suo nome;
 
<BR>- il primo byte di ciascuna porzione di memoria indica la lunghezza in byte della porzione stessa (nella quale sono indicati - come prima detto - il tipo di file ed il suo nome). Nel codice Gambas, sotto mostrato, la lunghezza, espressa in byte, sommata all'indice del byte che la rappresenta, specifica in sostanza l'indice dell'area di memoria, puntata dal ''Puntatore'', dell'analogo byte successivo che rappresenta sia l'inizio della porzione di memoria contenente il nome dell'altro eventuale file, sia ovviamente la lunghezza in byte di tale ulteriore utile porzione;
 
<BR>- il primo byte di ciascuna porzione di memoria indica la lunghezza in byte della porzione stessa (nella quale sono indicati - come prima detto - il tipo di file ed il suo nome). Nel codice Gambas, sotto mostrato, la lunghezza, espressa in byte, sommata all'indice del byte che la rappresenta, specifica in sostanza l'indice dell'area di memoria, puntata dal ''Puntatore'', dell'analogo byte successivo che rappresenta sia l'inizio della porzione di memoria contenente il nome dell'altro eventuale file, sia ovviamente la lunghezza in byte di tale ulteriore utile porzione;
Riga 38: Riga 37:
 
   Dim b As Byte
 
   Dim b As Byte
 
   Dim offset As Integer
 
   Dim offset As Integer
   
+
    Print "TIPI di File:"
+
  Print "TIPI di File:"
    Print " 0 = Sconosciuto  -  1 = Named pipe (FIFO)  -  2 = Character device  -  4 = Directory"
+
  Print " 0 = Sconosciuto  -  1 = Named pipe (FIFO)  -  2 = Character device  -  4 = Directory"
    Print " 6 = Block device  -  8 = Regular file      -  10 = Symbolic link    -  12 = UNIX domain socket  -  14 = Whiteout inode"
+
  Print " 6 = Block device  -  8 = Regular file      -  10 = Symbolic link    -  12 = UNIX domain socket  -  14 = Whiteout inode"
    Print "__________________________________________________________________________________________________________________________\n"
+
  Print "__________________________________________________________________________________________________________________________\n"
   
+
 
    directory = "<FONT Color=gray>''/percorso/della/Directory''</font>"
+
  directory = "<FONT Color=gray>''/percorso/della/Directory''</font>"
    Print "File contenuti nella Directory: "; directory
+
  Print "File contenuti nella Directory: "; directory
    Print "\nTipo  -  Nome file"
+
  Print "\nTipo  -  Nome file"
   
+
 
    drct = opendir(directory)
+
  drct = opendir(directory)
   
+
 
    dr = readdir(drct)
+
  dr = readdir(drct)
   
+
 
    offset = 64
+
  offset = 16
   
+
 
    While Byte@(dr + offset) > 0
+
  While Byte@(dr + offset) > 0
      b = Byte@(dr + offset + 2)
+
    b = Byte@(dr + offset + 2)
      Print " "; b; "        "; String@(dr + offset + 3)
+
    Print " "; b; "        "; String@(dr + offset + 3)
      offset += Byte@(dr + offset)
+
    offset += Byte@(dr + offset)
    Wend
+
  Wend
   
+
    closedir(drct)
+
  closedir(drct)
   
+
 
 
  '''End'''
 
  '''End'''
  
Riga 98: Riga 97:
 
   Dim ddrr As New Dirent[]
 
   Dim ddrr As New Dirent[]
 
   Dim i, n As Integer
 
   Dim i, n As Integer
    
+
  dirstream = opendir("/tmp")
+
   dirstream = opendir("/tmp")
  If dirstream = 0 Then Error.Raise("Impossibile aprire la directory prescelta !")
+
  If dirstream == 0 Then Error.Raise("Impossibile aprire la directory prescelta !")
   
 
  dr = readdir(dirstream)
 
  If IsNull(dr) Then Error.Raise("Impossibile leggere nella directory prescelta !")
 
 
    
 
    
  While True
+
  dr = readdir(dirstream)
   
+
  If dr == 0 Then Error.Raise("Impossibile leggere nella directory prescelta !")
    If Long@(dr + i) = 0 Then Break
+
   
+
  While Long@(dr + i) <> 0 Then Break
    With drnt = New Dirent
+
    With drnt = New Dirent
      .d_ino = Long@(dr + i)              <FONT Color=gray>' ''d_ino (Inode number)''</font>
+
      .d_ino = Long@(dr + i)              <FONT Color=gray>' ''d_ino (Inode number)''</font>
      .d_off = Long@(dr + i + 8)          <FONT Color=gray>' ''d_off (current position in the directory stream)''</font>
+
      .d_off = Long@(dr + i + 8)          <FONT Color=gray>' ''d_off (current position in the directory stream)''</font>
      .d_reclen = Short@(dr + i + 16)    <FONT Color=gray>' ''d_reclen (Length of this record)''</font>
+
      .d_reclen = Short@(dr + i + 16)    <FONT Color=gray>' ''d_reclen (Length of this record)''</font>
      .d_type = Byte@(dr + i + 18)        <FONT Color=gray>' ''d_type (Type of file)''</font>
+
      .d_type = Byte@(dr + i + 18)        <FONT Color=gray>' ''d_type (Type of file)''</font>
      .d_name = New Byte[]
+
      .d_name = New Byte[]
      For n = 0 To (Byte@(dr + i + 16) - 19) - 1
+
      For n = 0 To (Byte@(dr + i + 16) - 19) - 1
        .d_name.Push(Byte@(dr + i + 19 + n))
+
        .d_name.Push(Byte@(dr + i + 19 + n))
      Next
+
      Next
    End With
+
    End With
     
+
    ddrr.Push(drnt)
    ddrr.Push(drnt)
+
    i += Short@(dr + i + 16)
   
+
  Wend
    i += Short@(dr + i + 16)
+
     
+
  closedir(dirstream)
  Wend
 
 
 
  closedir(dirstream)
 
   
 
  Verifica(ddrr)
 
 
    
 
    
 +
  Verifica(ddrr)
 +
 
 
  '''End'''
 
  '''End'''
 
 
   
 
   
 
  '''Private''' Procedure Verifica(dd As Dirent[])
 
  '''Private''' Procedure Verifica(dd As Dirent[])
Riga 137: Riga 129:
 
   Dim d As Dirent
 
   Dim d As Dirent
 
    
 
    
  For Each d In dd
+
  For Each d In dd
    With d
+
    With d
      Print "Tipo di file: "; tipi[.d_type]
+
      Print "Tipo di file: "; tipi[.d_type]
      Print "Nome file:    "; String@(.d_name.Data)
+
      Print "Nome file:    "; String@(.d_name.Data)
      Print
+
      Print
    End With
+
    End With
  Next
+
  Next
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 170: Riga 162:
 
   Dim ini As Integer
 
   Dim ini As Integer
 
   Dim tipi As String[]
 
   Dim tipi As String[]
 
+
  tipi = ["Sconosciuto", "Pipe/FIFO", "Character device", Null, "Directory", Null, "Block device", Null, "File regolare",
+
  tipi = ["Sconosciuto", "Pipe/FIFO", "Character device", Null, "Directory", Null, "Block device", Null, "File regolare",
          Null, "Collegamento simbolico", Null, "Local-domain socket", Null, "DT_WHT"]
+
          Null, "Collegamento simbolico", Null, "Local-domain socket", Null, "DT_WHT"]
 
    
 
    
 
  <FONT Color=gray>' ''Conosciamo la "posizione" del primo valore utile, corrispondente al membro "c_reclen" della Struttura esterna "dirent":''</font>
 
  <FONT Color=gray>' ''Conosciamo la "posizione" del primo valore utile, corrispondente al membro "c_reclen" della Struttura esterna "dirent":''</font>
  ini = SizeOf(gb.Long) * 2
+
  ini = SizeOf(gb.Long) * 2
 
+
 
  dp = opendir("/tmp")
+
  dp = opendir("/tmp")
  If dp = 0 Then Error.Raise("Impossibile aprire la cartella !")
+
  If dp == 0 Then Error.Raise("Impossibile aprire la cartella !")
 
+
  dirent = readdir(dp)
+
  dirent = readdir(dp)
 
+
  If dirent == 0 Then Error.Raise("Errore !")
  Do
+
 
 
+
  Repeat 
 
  <FONT Color=gray>' ''Conosciamo il nome ed il tipo del corrente file individuato:''</font>
 
  <FONT Color=gray>' ''Conosciamo il nome ed il tipo del corrente file individuato:''</font>
    Print String@(dirent + ini + 3); Space(16); tipi[Byte@(dirent + ini + 2)]
+
    Print String@(dirent + ini + 3); Space(16); tipi[Byte@(dirent + ini + 2)]
 +
<FONT Color=gray>' ''Conosciamo la "posizione" del successivo valore corrispondente al membro "c_reclen" della Struttura esterna "dirent":''</font>
 +
    ini += CInt(Short@(dirent + ini))
 +
  Until Short@(dirent + ini) == 0
 
   
 
   
<FONT Color=gray>' ''Conosciamo la "posizione" del successivo valore corrispondente al membro "c_reclen" della Struttura esterna "dirent":''</font>
+
  closedir(dp)
    ini += CInt(Short@(dirent + ini))
+
   
 
 
  Loop Until Short@(dirent + ini) = 0
 
 
 
  closedir(dp)
 
     
 
 
  '''End'''
 
  '''End'''
 
  
  

Versione attuale delle 21:03, 5 set 2022

Come si sa, per leggere i file contenuti in una Directory, in Gambas si utilizza la comoda funzione "Dir()".

In questa pagina viene mostrato come utilizzare alcune risorse dichiarate nel file header "usr/include/dirent.h ", per conoscere i file presenti in una Directory.

E' necessario richiamare in Gambas la libreria condivisa: "libc.so.6 ".

Mostriamo di seguito due codici possibili.


1° esempio

E' sufficiente richiamare tre funzioni esterne, dichiarate nel file header dirent.h. I dati saranno immagazzinati in un'area di memoria, creata dalla funzione esterna "readdir()" e puntata da apposita variabile di tipo Puntatore. Si procederà alla dereferenziazione di detto Puntatore mediante le apposite funzioni di dereferenziazione previste da Gambas, tenendo comunque tenendo ben presente che:
- i dati utili per la lettura della Dirctory iniziano dal byte di indice 16 dell'area di memoria puntata dal Puntatore;
- l'area di memoria utile è suddivisa in varie porzioni contenenti - quali dati utili alla conoscenza dei file presenti nella Directory - il tipo di file ed il suo nome;
- il primo byte di ciascuna porzione di memoria indica la lunghezza in byte della porzione stessa (nella quale sono indicati - come prima detto - il tipo di file ed il suo nome). Nel codice Gambas, sotto mostrato, la lunghezza, espressa in byte, sommata all'indice del byte che la rappresenta, specifica in sostanza l'indice dell'area di memoria, puntata dal Puntatore, dell'analogo byte successivo che rappresenta sia l'inizio della porzione di memoria contenente il nome dell'altro eventuale file, sia ovviamente la lunghezza in byte di tale ulteriore utile porzione;
- il secondo byte è sempre uguale a zero;
- il terzo byte indica il "tipo" di file, di cui viene riportato nella corrente porzione di memoria - come prima detto - il tipo di file ed il suo nome;
- dal quarto byte (e fino al byte precedente quello che indica la lunghezza della successiva porzione di memoria contenente il tipo di un altro eventuale file ed il suo nome) iniziano i caratteri che identificano il nome del corrente file.

Library "libc:6"
 
' DIR *opendir (const char *__name)
' Open a directory stream on NAME.
Private Extern opendir(name As String) As Pointer

' struct dirent *readdir (DIR *__dirp)
' Read a directory entry from DIRP.
Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent

' int closedir (DIR *__dirp)
' Close the directory stream DIRP.
Private Extern closedir(dirp As Pointer) As Integer


Public Sub Main()
 
 Dim directory As String
 Dim drct, dr As Pointer
 Dim b As Byte
 Dim offset As Integer

 Print "TIPI di File:"
 Print " 0 = Sconosciuto   -  1 = Named pipe (FIFO)  -   2 = Character device  -   4 = Directory"
 Print " 6 = Block device  -  8 = Regular file       -  10 = Symbolic link     -  12 = UNIX domain socket  -  14 = Whiteout inode"
 Print "__________________________________________________________________________________________________________________________\n"
 
 directory = "/percorso/della/Directory"
 Print "File contenuti nella Directory: "; directory
 Print "\nTipo  -  Nome file"
 
 drct = opendir(directory)
 
 dr = readdir(drct)
 
 offset = 16
 
 While Byte@(dr + offset) > 0
   b = Byte@(dr + offset + 2)
   Print " "; b; "        "; String@(dr + offset + 3)
   offset += Byte@(dr + offset)
 Wend

 closedir(drct)
 
End


2° esempio

Library "libc:6"
 
Public Struct dirent
  d_ino As Long
  d_off As Long
  d_reclen As Short
  d_type As Byte
  d_name As Byte[]
End Struct

Private tipi As String[] = ["DT_UNKNOWN", "DT_FIFO", "DT_CHR", "", "DT_DIR", "", "DT_BLK",
                            "", "DT_REG", "", "DT_LNK", "", "DT_SOCK", "", "DT_WHT"]

' DIR *opendir (const char *__name)
' Open a directory stream on NAME.
Private Extern opendir(name As String) As Pointer

' struct dirent *readdir (DIR *__dirp)
' Read a directory entry from DIRP.
Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent

' int closedir (DIR *__dirp)
' Close the directory stream DIRP.
Private Extern closedir(dirp As Pointer) As Integer


Public Sub Main()

 Dim dr, dirstream As Pointer
 Dim drnt As Dirent
 Dim ddrr As New Dirent[]
 Dim i, n As Integer

 dirstream = opendir("/tmp")
 If dirstream == 0 Then Error.Raise("Impossibile aprire la directory prescelta !")
  
 dr = readdir(dirstream)
 If dr == 0 Then Error.Raise("Impossibile leggere nella directory prescelta !")

 While Long@(dr + i) <> 0 Then Break
   With drnt = New Dirent
     .d_ino = Long@(dr + i)              ' d_ino (Inode number)
     .d_off = Long@(dr + i + 8)          ' d_off (current position in the directory stream)
     .d_reclen = Short@(dr + i + 16)     ' d_reclen (Length of this record)
     .d_type = Byte@(dr + i + 18)        ' d_type (Type of file)
     .d_name = New Byte[]
     For n = 0 To (Byte@(dr + i + 16) - 19) - 1
       .d_name.Push(Byte@(dr + i + 19 + n))
     Next
   End With
   ddrr.Push(drnt)
   i += Short@(dr + i + 16)
 Wend

 closedir(dirstream)
  
 Verifica(ddrr)
 
End

Private Procedure Verifica(dd As Dirent[])
 
 Dim d As Dirent
 
 For Each d In dd
   With d
     Print "Tipo di file: "; tipi[.d_type]
     Print "Nome file:    "; String@(.d_name.Data)
     Print
   End With
 Next
  
End


3° esempio

Lettura dei file contenuti nella cartella /tmp:

Library "libc:6"

' DIR *opendir (const char *__name)
' Open a directory stream on NAME.
Private Extern opendir(__name As String) As Pointer

' struct dirent *readdir (DIR *__dirp)
' Read a directory entry from DIRP.
Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent

' int closedir (DIR *__dirp)
' Close the directory stream DIRP.
Private Extern closedir(__dirp As Pointer) As Integer


Public Sub Main()
 
 Dim dp, dirent As Pointer
 Dim ini As Integer
 Dim tipi As String[]

 tipi = ["Sconosciuto", "Pipe/FIFO", "Character device", Null, "Directory", Null, "Block device", Null, "File regolare",
         Null, "Collegamento simbolico", Null, "Local-domain socket", Null, "DT_WHT"]
  
' Conosciamo la "posizione" del primo valore utile, corrispondente al membro "c_reclen" della Struttura esterna "dirent":
 ini = SizeOf(gb.Long) * 2
 
 dp = opendir("/tmp")
 If dp == 0 Then Error.Raise("Impossibile aprire la cartella !")

 dirent = readdir(dp)
 If dirent == 0 Then Error.Raise("Errore !")
 
 Repeat  
' Conosciamo il nome ed il tipo del corrente file individuato:
   Print String@(dirent + ini + 3); Space(16); tipi[Byte@(dirent + ini + 2)]
' Conosciamo la "posizione" del successivo valore corrispondente al membro "c_reclen" della Struttura esterna "dirent":
   ini += CInt(Short@(dirent + ini))
 Until Short@(dirent + ini) == 0

 closedir(dp)
   
End


Riferimenti