Differenze tra le versioni di "Leggere il contenuto di una Directory mediante le risorse dichiarate nel file header "dirent.h""
Riga 6: | Riga 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: | 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>64</font> dell'area di memoria puntata dal ''Puntatore''; | ||
Riga 14: | Riga 17: | ||
<BR>- 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; | <BR>- 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; | ||
<BR>- 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. | <BR>- 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" | Library "libc:6" | ||
− | + | ||
<FONT Color=gray>' ''DIR *opendir (const char *__name)'' | <FONT Color=gray>' ''DIR *opendir (const char *__name)'' | ||
' ''Open a directory stream on NAME.''</font> | ' ''Open a directory stream on NAME.''</font> | ||
Riga 24: | Riga 24: | ||
<FONT Color=gray>' ''struct dirent *readdir (DIR *__dirp)'' | <FONT Color=gray>' ''struct dirent *readdir (DIR *__dirp)'' | ||
− | ' Read a directory entry from DIRP.''</font> | + | ' ''Read a directory entry from DIRP.''</font> |
Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent | Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent | ||
<FONT Color=gray>' ''int closedir (DIR *__dirp)'' | <FONT Color=gray>' ''int closedir (DIR *__dirp)'' | ||
− | ' Close the directory stream DIRP.''</font> | + | ' ''Close the directory stream DIRP.''</font> |
Private Extern closedir(dirp As Pointer) As Integer | Private Extern closedir(dirp As Pointer) As Integer | ||
Riga 35: | Riga 35: | ||
Dim directory As String | Dim directory As String | ||
− | Dim | + | Dim drct, dr As Pointer |
Dim b As Byte | Dim b As Byte | ||
Dim offset As Integer | Dim offset As Integer | ||
Riga 44: | Riga 44: | ||
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) | |
− | dr = readdir( | + | dr = readdir(drct) |
offset = 64 | offset = 64 | ||
Riga 60: | Riga 60: | ||
Wend | Wend | ||
− | closedir( | + | 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"] | ||
+ | |||
+ | <FONT Color=gray>' ''DIR *opendir (const char *__name)'' | ||
+ | ' ''Open a directory stream on NAME.''</font> | ||
+ | Private Extern opendir(name As String) As Pointer | ||
+ | |||
+ | <FONT Color=gray>' ''struct dirent *readdir (DIR *__dirp)'' | ||
+ | ' ''Read a directory entry from DIRP.''</font> | ||
+ | Private Extern readdir(__dirp As Pointer) As Pointer 'Dirent | ||
+ | |||
+ | <FONT Color=gray>' ''int closedir (DIR *__dirp)'' | ||
+ | ' ''Close the directory stream DIRP.''</font> | ||
+ | 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 IsNull(dr) Then Error.Raise("Impossibile leggere nella directory prescelta !") | ||
+ | |||
+ | While True | ||
+ | |||
+ | If 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''' | '''End''' | ||
Versione delle 16:49, 20 ago 2016
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 dinamica condivisa: "libc: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 64 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 = 64 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 IsNull(dr) Then Error.Raise("Impossibile leggere nella directory prescelta !") While True If 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