Differenze tra le versioni di "Leggere il contenuto di una Directory mediante le risorse dichiarate nel file header "dirent.h""
(Una versione intermedia di uno stesso utente non è mostrata) | |||
Riga 1: | Riga 1: | ||
− | Come si sa, per leggere i file contenuti in una Directory, in Gambas si utilizza la comoda funzione | + | 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 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 | + | 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> | + | <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 " 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 = "<FONT Color=gray>''/percorso/della/Directory''</font>" | |
− | + | 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''' | '''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") | |
− | + | 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) <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_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_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''' | '''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 | |
− | + | With d | |
− | + | Print "Tipo di file: "; tipi[.d_type] | |
− | + | Print "Nome file: "; String@(.d_name.Data) | |
− | + | Print | |
− | + | End With | |
− | + | 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", | |
− | + | 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 | |
− | + | ||
− | + | dp = opendir("/tmp") | |
− | + | If dp == 0 Then Error.Raise("Impossibile aprire la cartella !") | |
− | + | ||
− | + | dirent = readdir(dp) | |
− | + | If dirent == 0 Then Error.Raise("Errore !") | |
− | + | ||
− | + | 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)] | |
+ | <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 | ||
− | + | 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