Differenze tra le versioni di "Sapere se un file di nome sconosciuto è stato creato o distrutto"
Riga 213: | Riga 213: | ||
'''Public''' Sub Button1_Click() | '''Public''' Sub Button1_Click() | ||
+ | |||
+ | <FONT Color=gray>' ''Va in chiusura...''</font> | ||
+ | bo = True | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | Il precedente codice può essere ovviamente inserito - con le dovute variazioni - anche in un'applicazione ''a riga di comando'': | ||
+ | Private Const BUFFER As Long = 4096 | ||
+ | Private bo As Boolean | ||
+ | |||
+ | |||
+ | Library "libc:6" | ||
+ | |||
+ | Public Struct inotify_event | ||
+ | wd As Integer | ||
+ | mask As Integer | ||
+ | cookie As Integer | ||
+ | lenI As Integer | ||
+ | name[32] As Byte | ||
+ | End Struct | ||
+ | |||
+ | Public Struct pollfd | ||
+ | fd As Integer | ||
+ | events As Short | ||
+ | revents As Short | ||
+ | End Struct | ||
+ | |||
+ | Private Const IN_ACCESS As Integer = 1 <FONT Color=gray>' ''File was accessed.''</font> | ||
+ | Private Const IN_MODIFY As Integer = 2 <FONT Color=gray>' ''File was modified.''</font> | ||
+ | Private Const IN_ATTRIB As Integer = 4 <FONT Color=gray>' ''Metadata changed.''</font> | ||
+ | Private Const IN_CLOSE_WRITE As Integer = 8 <FONT Color=gray>' ''Writtable file was closed.''</font> | ||
+ | Private Const IN_CLOSE_NOWRITE As Integer = &10 <FONT Color=gray>' ''Unwrittable file closed.''</font> | ||
+ | Private Const IN_OPEN As Integer = &20 <FONT Color=gray>' ''File was opened.''</font> | ||
+ | Private Const IN_MOVED_FROM As Integer = &40 <FONT Color=gray>' ''File was moved From X.''</font> | ||
+ | Private Const IN_MOVED_TO As Integer = &80 <FONT Color=gray>' ''File was moved To Y.''</font> | ||
+ | Private Const IN_CREATE As Integer = &100 <FONT Color=gray>' ''Subfile was created.''</font> | ||
+ | Private Const IN_DELETE As Integer = &200 <FONT Color=gray>' ''Subfile was deleted.''</font> | ||
+ | Private Const IN_DELETE_SELF As Integer = &400 <FONT Color=gray>' ''Self was deleted.''</font> | ||
+ | Private Const IN_MOVE_SELF As Integer = &800 <FONT Color=gray>' ''Self was moved.''</font> | ||
+ | Private Const IN_UNMOUNT As Integer = &2000 <FONT Color=gray>' ''Backing fs was unmounted.''</font> | ||
+ | Private Const IN_Q_OVERFLOW As Integer = &4000 <FONT Color=gray>' ''Event queued overflowed.''</font> | ||
+ | Private Const IN_IGNORED As Integer = &8000 <FONT Color=gray>' ''File was ignored.''</font> | ||
+ | Private Const IN_ISDIR As Integer = &40000000 <FONT Color=gray>' ''Event occurred against dir.''</font> | ||
+ | Private Const IN_ALL_EVENTS As Integer = 4095 | ||
+ | |||
+ | Private Const POLLIN As Short = 1 | ||
+ | |||
+ | <FONT Color=gray>' ''int inotify_init (void) | ||
+ | ' ''Create and initialize inotify instance.''</font> | ||
+ | Private Extern inotify_init() As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''int inotify_add_watch (int __fd, const char *__name, uint32_t __mask) | ||
+ | ' ''Add watch of object NAME to inotify instance FD.''</font> | ||
+ | Private Extern inotify_add_watch(__fd As Integer, name As String, __mask As Integer) As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''int inotify_rm_watch (int __fd, int __wd) | ||
+ | ' ''Remove the watch specified by WD from the inotify instance FD.''</font> | ||
+ | Private Extern inotify_rm_watch(__fd As Integer, __wd As Integer) As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) | ||
+ | ' ''Poll the file descriptors described by the NFDS structures starting at FDS.''</font> | ||
+ | Private Extern poll(__fds As Pollfd, __nfds As Long, __timeout As Integer) As Integer | ||
+ | |||
+ | <FONT Color=gray>' ''ssize_t read (int __fd, void *__buf, size_t __nbytes) | ||
+ | ' ''Read NBYTES into BUF from FD.''</font> | ||
+ | Private Extern read_C(__fd As Integer, __buf As Pointer, __nbytes As Long) As Long Exec "read" | ||
+ | |||
+ | <FONT Color=gray>' ''int close (int __fd) | ||
+ | ' ''Close the file descriptor FD.''</font> | ||
+ | Private Extern close_C(__fd As Integer) As Integer Exec "close" | ||
+ | |||
+ | |||
+ | '''Public''' Sub Form_Open() | ||
+ | |||
+ | Dim percorso_file As String | ||
+ | Dim fd, wa As Integer | ||
+ | Dim buf, p As Pointer | ||
+ | Dim letti As Long | ||
+ | Dim evento As New Inotify_event | ||
+ | Dim pl As New Pollfd | ||
+ | |||
+ | <FONT Color=gray>' '' == Poniamo sotto osservazione la Cartella "/tmp", qualora venga creato o venga distrutto un file ==''</font> | ||
+ | |||
+ | percorso_file = "/tmp" | ||
+ | |||
+ | fd = inotify_init() | ||
+ | If fd = -1 Then Error.Raise("Impossibile inizializare 'inotify' !") | ||
+ | |||
+ | wa = inotify_add_watch(fd, percorso_file, IN_ALL_EVENTS) | ||
+ | If wa = -1 Then Error.Raise("Errore alla funzione esterna 'inotify_add_watch()' !") | ||
+ | |||
+ | Print "Cartella '"; percorso_file; "' ...sotto osservazione !\n" | ||
+ | |||
+ | buf = Alloc(CInt(BUFFER)) | ||
+ | |||
+ | While bo = False | ||
+ | |||
+ | pl.fd = fd | ||
+ | pl.events = POLLIN | ||
+ | |||
+ | letti = poll(pl, 1, 100) | ||
+ | Select Case letti | ||
+ | Case -1 | ||
+ | Error.Raise("Errore alla funzione esterna 'poll()' !") | ||
+ | Case 1 | ||
+ | letti = read_C(fd, buf, BUFFER) | ||
+ | If letti = -1 Then Error.Raise("Errore alla funzione esterna 'read_C()' !") | ||
+ | End Select | ||
+ | |||
+ | p = buf | ||
+ | |||
+ | While p < buf + CInt(letti) | ||
+ | evento = p | ||
+ | If evento.mask And IN_CREATE Then Print "Creato il nuevo file: "; String@(evento.name.Data) | ||
+ | If evento.mask And IN_DELETE Then Print "Eliminato il file: "; String@(evento.name.Data) | ||
+ | If evento.mask And IN_MOVED_FROM Then Print "Spostato nel cestino il file: "; String@(evento.name.Data) | ||
+ | p += 16 + evento.lenI | ||
+ | Wend | ||
+ | |||
+ | Wait 0.1 | ||
+ | |||
+ | Wend | ||
+ | |||
+ | |||
+ | <FONT Color=gray>' ''Libera memoria in chiusura:''</font> | ||
+ | Free(buf) | ||
+ | inotify_rm_watch(fd, wa) | ||
+ | close_C(fd) | ||
+ | Quit | ||
+ | |||
+ | '''End''' | ||
+ | |||
+ | |||
+ | '''Public''' Sub Application_Read() | ||
<FONT Color=gray>' ''Va in chiusura...''</font> | <FONT Color=gray>' ''Va in chiusura...''</font> |
Versione delle 20:21, 12 mar 2016
Può accadere che si voglia sapere se un qualsiasi file, del quale non è conosciuto a priori il nome, sia stato creato o distrutto all'interno di una determinata Cartella.
Per mostrare un possibile codice, faremo l'esempio della immediata verifica della creazione nella cartella "/dev/pts" del file speciale di tipo pts di un Terminale nel momento in cui tale Terminale viene aperto:
Public Sub Form_Open() Dim b As Byte Dim ss As New String[] Dim s, dr As String dr = "/dev/pts" ' Assegna ad una variabile vettoriale il nome dei file presenti nella cartella "/dev/pts": b = Dir(dr, Null, gb.Device).Copy() ' Resta in attesa sino a quando un Terminale non è stato aperto: Do Wait 0.01 Loop Until Dir(dr, Null, gb.Device).Count = ss.Count + 1 ' Effettua la verifica di quale file speciale di tipo "pts" corrisponde a quello del Terminale appena aperto: ' il nuovo file "pts", non presente nella variabile vettore di tipo stringa, è quello del Terminale: For Each s In Dir(dr, Null, gb.Device) If Not ss.Exist(s) Then Exit Next Print s End
Verificare la creazione e/o la distruzione di un file
Mostriamo di seguito un possibile codice con l'uso dell'ooggetto Timer per verificare la creazione e/o la distruzione di un file all'interno ad esempio della Cartella "/tmp". L'uso dell'oggetto Timer, ci consentirà di non chiudere il programma all'interno di un ciclo infinito.
Il seguente codice può essere ovviamente inserito anche in un'applicazione a riga di comando.
Private tempus As Timer Private ss As New String[] Private dr As String Public Sub Form_Open() Dim b As Byte Dim ss As New String[] Me.Show dr = "/tmp" ss = Dir(dr, Null, gb.File).Copy() With tempus = New Timer As "Tempus" .Delay = 100 .Start End With End Public Sub Tempus_Timer() Dim b As Byte Dim s As String If ss.Count <> Dir(dr, Null, gb.File).Count Then For Each s In Dir(dr, Null, gb.File) If Not ss.Exist(s) Then Print "\nCreato il file: "; s ss = Dir(dr, Null, gb.File).Copy() Endif Next For Each s In ss If Not Exist(dr &/ s) Then Print "\nDistrutto il file: "; s ss = Dir(dr, Null, gb.File).Copy() Endif Next Endif End
Uso delle risorse del API di inotify
E' possibile anche utilizzare le risorse inotify, dichiarate nel file header sys/inotify.h .
Mostriamo un esempio, nel quale si verificheranno la creazione e la distruzione di un determinato file mediante due Button:
Private Const BUFFER As Long = 4096 Private bo As Boolean Library "libc:6" Public Struct inotify_event wd As Integer mask As Integer cookie As Integer lenI As Integer name[32] As Byte End Struct Public Struct pollfd fd As Integer events As Short revents As Short End Struct Private Const IN_ACCESS As Integer = 1 ' File was accessed. Private Const IN_MODIFY As Integer = 2 ' File was modified. Private Const IN_ATTRIB As Integer = 4 ' Metadata changed. Private Const IN_CLOSE_WRITE As Integer = 8 ' Writtable file was closed. Private Const IN_CLOSE_NOWRITE As Integer = &10 ' Unwrittable file closed. Private Const IN_OPEN As Integer = &20 ' File was opened. Private Const IN_MOVED_FROM As Integer = &40 ' File was moved From X. Private Const IN_MOVED_TO As Integer = &80 ' File was moved To Y. Private Const IN_CREATE As Integer = &100 ' Subfile was created. Private Const IN_DELETE As Integer = &200 ' Subfile was deleted. Private Const IN_DELETE_SELF As Integer = &400 ' Self was deleted. Private Const IN_MOVE_SELF As Integer = &800 ' Self was moved. Private Const IN_UNMOUNT As Integer = &2000 ' Backing fs was unmounted. Private Const IN_Q_OVERFLOW As Integer = &4000 ' Event queued overflowed. Private Const IN_IGNORED As Integer = &8000 ' File was ignored. Private Const IN_ISDIR As Integer = &40000000 ' Event occurred against dir. Private Const IN_ALL_EVENTS As Integer = 4095 Private Const POLLIN As Short = 1 ' int inotify_init (void) ' Create and initialize inotify instance. Private Extern inotify_init() As Integer ' int inotify_add_watch (int __fd, const char *__name, uint32_t __mask) ' Add watch of object NAME to inotify instance FD. Private Extern inotify_add_watch(__fd As Integer, name As String, __mask As Integer) As Integer ' int inotify_rm_watch (int __fd, int __wd) ' Remove the watch specified by WD from the inotify instance FD. Private Extern inotify_rm_watch(__fd As Integer, __wd As Integer) As Integer ' int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) ' Poll the file descriptors described by the NFDS structures starting at FDS. Private Extern poll(__fds As Pollfd, __nfds As Long, __timeout As Integer) As Integer ' 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" ' int close (int __fd) ' Close the file descriptor FD. Private Extern close_C(__fd As Integer) As Integer Exec "close" Public Sub Form_Open() Dim percorso_file As String Dim fd, wa As Integer Dim buf, p As Pointer Dim letti As Long Dim evento As New Inotify_event Dim pl As New Pollfd Me.Show ' == Poniamo sotto osservazione la Cartella "/tmp", qualora venga creato o venga distrutto un file == percorso_file = "/tmp" fd = inotify_init() If fd = -1 Then Error.Raise("Impossibile inizializare 'inotify' !") wa = inotify_add_watch(fd, percorso_file, IN_ALL_EVENTS) If wa = -1 Then Error.Raise("Errore alla funzione esterna 'inotify_add_watch()' !") Print "Cartella '"; percorso_file; "' ...sotto osservazione !\n" buf = Alloc(CInt(BUFFER)) While bo = False pl.fd = fd pl.events = POLLIN letti = poll(pl, 1, 100) Select Case letti Case -1 Error.Raise("Errore alla funzione esterna 'poll()' !") Case 1 letti = read_C(fd, buf, BUFFER) If letti = -1 Then Error.Raise("Errore alla funzione esterna 'read_C()' !") End Select p = buf While p < buf + CInt(letti) evento = p If evento.mask And IN_CREATE Then Print "Creato il nuevo file: "; String@(evento.name.Data) If evento.mask And IN_DELETE Then Print "Eliminato il file: "; String@(evento.name.Data) If evento.mask And IN_MOVED_FROM Then Print "Spostato nel cestino il file: "; String@(evento.name.Data) p += 16 + evento.lenI Wend Wait 0.1 Wend ' Libera memoria in chiusura: Free(buf) inotify_rm_watch(fd, wa) close_C(fd) Me.Close End Public Sub Button1_Click() ' Va in chiusura... bo = True End
Il precedente codice può essere ovviamente inserito - con le dovute variazioni - anche in un'applicazione a riga di comando:
Private Const BUFFER As Long = 4096 Private bo As Boolean Library "libc:6" Public Struct inotify_event wd As Integer mask As Integer cookie As Integer lenI As Integer name[32] As Byte End Struct Public Struct pollfd fd As Integer events As Short revents As Short End Struct Private Const IN_ACCESS As Integer = 1 ' File was accessed. Private Const IN_MODIFY As Integer = 2 ' File was modified. Private Const IN_ATTRIB As Integer = 4 ' Metadata changed. Private Const IN_CLOSE_WRITE As Integer = 8 ' Writtable file was closed. Private Const IN_CLOSE_NOWRITE As Integer = &10 ' Unwrittable file closed. Private Const IN_OPEN As Integer = &20 ' File was opened. Private Const IN_MOVED_FROM As Integer = &40 ' File was moved From X. Private Const IN_MOVED_TO As Integer = &80 ' File was moved To Y. Private Const IN_CREATE As Integer = &100 ' Subfile was created. Private Const IN_DELETE As Integer = &200 ' Subfile was deleted. Private Const IN_DELETE_SELF As Integer = &400 ' Self was deleted. Private Const IN_MOVE_SELF As Integer = &800 ' Self was moved. Private Const IN_UNMOUNT As Integer = &2000 ' Backing fs was unmounted. Private Const IN_Q_OVERFLOW As Integer = &4000 ' Event queued overflowed. Private Const IN_IGNORED As Integer = &8000 ' File was ignored. Private Const IN_ISDIR As Integer = &40000000 ' Event occurred against dir. Private Const IN_ALL_EVENTS As Integer = 4095 Private Const POLLIN As Short = 1 ' int inotify_init (void) ' Create and initialize inotify instance. Private Extern inotify_init() As Integer ' int inotify_add_watch (int __fd, const char *__name, uint32_t __mask) ' Add watch of object NAME to inotify instance FD. Private Extern inotify_add_watch(__fd As Integer, name As String, __mask As Integer) As Integer ' int inotify_rm_watch (int __fd, int __wd) ' Remove the watch specified by WD from the inotify instance FD. Private Extern inotify_rm_watch(__fd As Integer, __wd As Integer) As Integer ' int poll (struct pollfd *__fds, nfds_t __nfds, int __timeout) ' Poll the file descriptors described by the NFDS structures starting at FDS. Private Extern poll(__fds As Pollfd, __nfds As Long, __timeout As Integer) As Integer ' 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" ' int close (int __fd) ' Close the file descriptor FD. Private Extern close_C(__fd As Integer) As Integer Exec "close" Public Sub Form_Open() Dim percorso_file As String Dim fd, wa As Integer Dim buf, p As Pointer Dim letti As Long Dim evento As New Inotify_event Dim pl As New Pollfd ' == Poniamo sotto osservazione la Cartella "/tmp", qualora venga creato o venga distrutto un file == percorso_file = "/tmp" fd = inotify_init() If fd = -1 Then Error.Raise("Impossibile inizializare 'inotify' !") wa = inotify_add_watch(fd, percorso_file, IN_ALL_EVENTS) If wa = -1 Then Error.Raise("Errore alla funzione esterna 'inotify_add_watch()' !") Print "Cartella '"; percorso_file; "' ...sotto osservazione !\n" buf = Alloc(CInt(BUFFER)) While bo = False pl.fd = fd pl.events = POLLIN letti = poll(pl, 1, 100) Select Case letti Case -1 Error.Raise("Errore alla funzione esterna 'poll()' !") Case 1 letti = read_C(fd, buf, BUFFER) If letti = -1 Then Error.Raise("Errore alla funzione esterna 'read_C()' !") End Select p = buf While p < buf + CInt(letti) evento = p If evento.mask And IN_CREATE Then Print "Creato il nuevo file: "; String@(evento.name.Data) If evento.mask And IN_DELETE Then Print "Eliminato il file: "; String@(evento.name.Data) If evento.mask And IN_MOVED_FROM Then Print "Spostato nel cestino il file: "; String@(evento.name.Data) p += 16 + evento.lenI Wend Wait 0.1 Wend ' Libera memoria in chiusura: Free(buf) inotify_rm_watch(fd, wa) close_C(fd) Quit End Public Sub Application_Read() ' Va in chiusura... bo = True End