2012-02-07 1 views
7

Ho una cartella in cui vengono copiati i file. Voglio guardarlo ed elaborare i file non appena vengono copiati nella directory. Sono in grado di rilevare quando un file si trova nella directory, tramite il polling (la mia attuale implementazione) o in alcuni test che utilizzano API di Windows da alcuni esempi che ho trovato online.C++ Directory Watching - Come rilevare la copia è terminata

Il problema è che rilevo quando il file viene creato per la prima volta e viene ancora copiato. Questo rende il mio programma, che ha bisogno di accedere al file, attraverso errori (perché il file non è ancora completo). Come posso rilevare non quando è iniziata la copia ma quando è terminata la copia? Sto usando C++ su Windows, quindi la risposta potrebbe dipendere dalla piattaforma ma, se possibile, preferirei che fosse indipendente dalla piattaforma.

+0

Ho trovato questa domanda solo pochi minuti fa: http://stackoverflow.com/questions/559659/how-to-know-a-file-is-finished-copying E 'molto simile al mio problema, ma il "approvato "La soluzione è lontana dall'essere elegante e funzionale. – petersaints

+0

Se il codice verrà eseguito in un contesto amministrativo, ad esempio, come servizio di sistema, è possibile utilizzare un giornale delle modifiche. Vedi http://msdn.microsoft.com/en-us/library/windows/desktop/aa363798%28v=vs.85%29.aspx –

+0

Considerando la possibilità di cose come la copia ingenua usando 'fread()'/'fwrite() 'Non penso che ci sia una soluzione generale. Non abbastanza robusto, ma forse rintracciando maniglie aperte sui file? –

risposta

4

È possibile utilizzare i file di blocco o una convenzione di denominazione speciale. Il più semplice è il secondo e dovrebbe funzionare in questo modo:

Dire che si desidera spostare un file denominato "fileA.txt" Quando lo si copia nella directory di destinazione, invece, copiarlo in "fileA.txt.partial" o qualcosa del genere. Quando la copia è completa, rinomina il file da "fileA.txt.partial" a "fileA.txt". Quindi l'aspetto di "fileA.txt" è atomico per quanto il programma di visione può vedere.

L'altra opzione menzionata in precedenza è il file di blocco. Quindi quando copi un file chiamato "fileA.txt", devi prima creare un file chiamato "fileA.txt.lock". Al termine della copia, è sufficiente eliminare il file di blocco. Quando il programma di visualizzazione vede "fileA.txt", dovrebbe verificare se "fileA.txt.lock" esiste, se lo fa, può attendere o rivedere quel file in futuro, se necessario.

+2

Bene, questa è una soluzione alternativa e potrebbe funzionare su altri ambienti. Ma in questo caso, sto parlando di file copiati da altri programmi/tramite l'esploratore di file in una cartella che viene guardata dal mio programma. In tal caso questo approccio è molto difficile da realizzare. – petersaints

+0

Non è sicuro che sia possibile se non si ha il controllo su come i file vengono copiati. –

2

Non si dovrebbe eseguire il polling. Utilizzare FindFirstChangeNotification (http://msdn.microsoft.com/en-us/library/windows/desktop/aa364417%28v=vs.85%29.aspx) per visualizzare una directory per le modifiche.

Quindi utilizzare le funzioni di attesa (http://msdn.microsoft.com/en-us/library/windows/desktop/ms687069%28v=vs.85%29.aspx) per attendere il verificarsi di notifiche di modifica.

Panoramica ed esempi qui: http://msdn.microsoft.com/en-us/library/windows/desktop/aa365261%28v=vs.85%29.aspx

Non sono sicuro di come esattamente il file di completamento scrittura può essere determinato. La risposta di Evan Teran è una buona idea.

+0

È esattamente perché il polling non è una buona idea che sto cercando di sostituirlo con qualcosa di meglio;) E sì! Ho trovato questi metodi e ho già una soluzione basata su questo: http://code.google.com/p/simplefilewatcher/. Il problema è determinare il completamento della scrittura del file. Quella libreria (che ho già leggermente modificato) usa ReadDirectoryChangesW che credo sia ancora più potente di FindFirstChangeNotification. – petersaints

+0

In una nota a margine, mi chiedo solo come Dropbox (ad esempio) si occupa di questo tipo di problemi. – petersaints

+0

Si potrebbe provare ad aprire il file per la scrittura esclusiva, che fallirà fino al completamento della copia. Probabilmente c'è un modo per bloccare quella condizione, invece di votarla, ma non la conosco a priori. –