2009-11-20 12 views
26

Desidero ricevere una notifica al mio codice quando viene modificato qualsiasi file in (direttamente o indirettamente) una determinata directory. Con "modificato", voglio dire che voglio che il mio codice venga avvisato ogni volta che il contenuto di un file viene alterato, rinominato o cancellato; o se viene aggiunto un nuovo file. Per la mia applicazione, ci possono essere migliaia di file.Notifica di modifica del filesystem a livello di file in Mac OS X

ho guardato come FSEvents, ma la sua Panoramica Tecnologia dice, in parte:

Il punto importante da togliere è che la granularità delle notifiche è ad un livello di directory. Ti dice solo che qualcosa nella directory è cambiato, ma non ti dice cosa è cambiato.

Si dice anche:

Il file di eventi del sistema API non è progettato anche per scoprire quando un particolare modifiche apportate ai file. Per tali scopi, il meccanismo dei kqueues è più appropriato.

Tuttavia, per utilizzare kqueue su un determinato file, è necessario aprire il file per ottenere un descrittore di file. Non è pratico gestire migliaia di descrittori di file (e probabilmente supererebbe comunque il numero massimo consentito di descrittori di file aperti).

Stranamente, in Windows, posso utilizzare la funzione ReadDirectoryChangesW() e fa esattamente ciò che voglio.

Quindi, come si può fare ciò che voglio in Mac OS X? Oppure, chiesto in un altro modo: come si potrebbe scrivere l'equivalente di ReadDirectoryChangesW() per Mac OS X nello spazio utente (e farlo in modo molto efficiente)?

risposta

6

Non ho provato io stesso, ma sembra che FSEvents è in grado di fornire le notifiche a livello di file come del 10,7 (Lion). Da the description of FSEventStreamCreateFlags:

kFSEventStreamCreateFlagFileEvents

Richiedi conferma a livello di file. Il tuo stream riceverà eventi su singoli file nella gerarchia che stai guardando invece di ricevere solo notifiche a livello di directory.Usa questa bandiera con attenzione perché genererà molti più eventi che senza di essa.

Disponibile in OS X v10.7 e versioni successive.

8

EDIT: non verificate, ma Konstantin indica di seguito che questo esempio di codice è obsoleta a partire dal 2012.

Non credo ci sia una specifica API per quello che stai cercando. Apple fornisce un codice di esempio per un problema simile chiamato Watcher. Non è quello che stai cercando, ma è il meglio che puoi fare a questo punto. Devi prendere istantanee della directory e rieseguire la scansione quando scopri qualcosa cambiato. Il tempo di modifica è la cosa migliore da verificare, ovviamente, se puoi fidarti del tempo di modifica.

Probabilmente è corretto che provare a registrarsi per un numero illimitato di kqueues sarebbe probabilmente impraticabile.

+0

In genere non mi piace la programmazione Windows e preferisco la programmazione Mac/Linux. Sembra strano che apparentemente almeno 1 cosa è più facile da fare in Windows. –

+3

Oh, ci sono molte cose più facili da fare su Windows. Prova a parlare SOAP usando Cocoa. NSArray è bello, ma a volte uno stile C# generico sarebbe molto gradito. Il Mac non ha nulla nemmeno vicino a ASP.NET (sto guardando te, WebObjects). Amo il cacao; è di gran lunga la migliore struttura che abbia mai incontrato. Ma chiunque pensi che sia tutto meglio per gli sviluppatori su Mac che su Windows non si è sviluppato molto su entrambi. Per cose come questa, stiamo tutti aspettando quel santo graal di zfs, che potrebbe rendere questo tipo di cose più facili e veloci. Un giorno ... (Microsoft ha i suoi sogni anche su winfs ...) –

+1

Il problema è che stai facendo un mucchio di programmazione Linux con la programmazione Mac. Questo è molto facile da fare su Linux con inotifywait. – MarkovCh1

-2

Si potrebbe voler verificare man fs_usage, anche se non è specifico di una directory e richiede i privilegi di root.

2

L'utilità più vicina (che io sappia) che corrisponde alle tue esigenze su Mac OS X è fslogger. Vedi il link per un codice descrizione, dmg e la fonte: OSXBook - fslogger