Ho bisogno di creare un programma java che creerà thread per cercare un file in una cartella particolare (cartella di origine) e scegliere immediatamente il file per il lavoro di processo (convertirlo in formato di file csv) una volta trovato il file nel cartella di origine. Il problema che sto affrontando ora è che il file che arriva alla cartella sorgente è di grandi dimensioni (lo strumento FTP è usato per copiare file dalla cartella server alla cartella sorgente), il thread sta selezionando quel file immediatamente prima di copiarlo completamente nella cartella sorgente e lanciare un'eccezione. Come posso interrompere il thread finché il file non viene copiato completamente nella cartella di origine ?. Deve selezionare il file per l'elaborazione solo dopo che il file è stato copiato completamente nella cartella di origine.Come gestire i file incompleti? Ottenere l'eccezione
risposta
Dando per scontato che non hanno alcun controllo sul processo FTP ...
lascia che sia così. Quando ottieni l'eccezione, prova ad elaborarla di nuovo la volta successiva. Ripeti finché il file non viene elaborato. È buono per mantenere alcuni attributi in caso di eccezione per controllarlo più tardi, come; nome, ultima modifica, dimensione.
Controllare l'eccezione esatta prima di decidere di elaborarlo in seguito, l'eccezione potrebbe verificarsi per qualche altro motivo.
Se si ha il controllo sul processo che esegue l'FTP, è possibile che sia possibile creare un "file di bandiera" nella directory di origine immediatamente dopo che il file ftp per il file grande è terminato.
Quindi il thread Java deve controllare la presenza di questo file di flag, se è presente, c'è un file pronto per essere elaborato nella directory di origine. Prima di elaborare il file grande, il thread dovrebbe rimuovere il file di flag.
Il file di bandiera può essere qualsiasi cosa (anche un file vuoto).
Si potrebbe provare cose diverse:
-
controllare ripetutamente la data dell'ultima modifica e la dimensione del file fino a quando non cambia più per un determinato periodo di tempo, poi elaborarlo.(Come sottolineato da qbeuek, questo non è né sicuro né deterministico.) - Solo file di processo con nomi che soddisfano determinati criteri (ad esempio * .dat). Modificare il processo di upload/download FTP per caricare/scaricare file con un nome diverso (ad esempio * .dat.temp) e rinominare i file una volta completati.
- Scaricare i file in una posizione diversa e spostarli nella directory di elaborazione una volta completati.
- Come ha detto l'aceto, se non funziona la prima volta, riprovare più tardi. :)
Non so perché abbiamo downvotes, a volte. La gente inizia a sparare ovunque. 100 reputazione è troppo bassa per downvotare qualcuno. Deve essere più alto, può essere 1000 o 2000. –
Beh, a volte io voto fino in fondo per bilanciare i downvotes, dando al votatario +8 punti che altrimenti non riceverebbero, quindi è qualcosa. In questo caso avrei comunque votato la tua risposta, dura. – itsadok
ti ho votato perché il primo elemento nell'elenco dei tuoi suggerimenti non è sicuro né deterministico. – qbeuek
Il modo più sicuro è quello di scaricare il file in una posizione diversa e quindi spostarlo nella cartella di destinazione.
Un'altra variante menzionata da Bombe è quella di cambiare il nome del file in un'altra estensione dopo il download e cercare solo i file con tale estensione.
+1 Questo non è il modo più sicuro, ma l'unico modo per farlo. Tutte le altre opzioni sprecano risorse o sono insicure :) –
Ho letto solo il file che non è in modalità di scrittura. Questo è più sicuro in quanto ciò significa che nessun altro processo sta scrivendo in questo file. È possibile verificare se il file non è in modalità di scrittura utilizzando il metodo canWrite della classe File.
Questa soluzione funziona bene per me poiché ho anche lo stesso identico scenario che stai affrontando.
Se il sistema operativo è Linux e il kernel> 2.6.13, è possibile utilizzare l'API di notifica eventi del file system denominata inotify. Qui c'è un'implementazione Java: https://bitbucket.org/nbargnesi/inotify-java.
Ecco un esempio di codice (fortemente ispirato al sito Web).
try {
Inotify i = new Inotify();
InotifyEventListener e = new InotifyEventListener() {
@Override
public void filesystemEventOccurred(InotifyEvent e) {
System.out.println("inotify event occurred!");
}
@Override
public void queueFull(EventQueueFull e) {
System.out.println("inotify event queue: " + e.getSource() +
" is full!");
}
};
i.addInotifyEventListener(e);
i.addWatch(System.getProperty("user.home"), Constants.IN_CLOSE_WRITE);
} catch (UnsatisfiedLinkError e) {
System.err.println("unsatisfied link error");
} catch (UserLimitException e) {
System.err.println("user limit exception");
} catch (SystemLimitException e) {
System.err.println("system limit exception");
} catch (InsufficientKernelMemoryException e) {
System.err.println("insufficient kernel memory exception");
}
Questo è in Grails e sto usando FileUtils
libreria dal Apache Commons fama. La funzione sizeof
restituisce la dimensione in byte.
def fileModified = sourceFile.lastModified()
def fileSize = FileUtils.sizeOf(sourceFile)
Thread.sleep(3000) //sleep to calculate size difference if the file is currently getting copied
if((fileSize != FileUtils.sizeOf(sourceFile)) && (fileModified != sourceFile.lastModified())) //the file is still getting copied to return
{
if(log.infoEnabled)
log.info("File is getting copied!")
return
}
Thread.sleep(1000) //breather for picking up file just copied.
prega di notare che questo dipende anche da ciò che di utilità o sistema operativo utilizzato per trasferire i file. La scommessa più sicura è copiare il file che è stato copiato o è stato copiato in diversi file o directory. Il processo di copia è robusto e ti assicura che il file è presente dopo il processo di copia. Quello che sto usando è da API commons.
FileUtils.copyFileToDirectory (File f, directory D)
Se si sta copiando un file enorme che è in procinto di ottenere copiato attenzione che questo richiederà tempo e come si potrebbe iniziare questo in filo parallelo o meglio avere una singola applicazione dedicata per il processo di trasferimento.
- 1. Come gestire i file hdf5 in R?
- 2. Come gestire i file caricati in webapp2
- 3. Come gestire i file temporanei in ASP.NET?
- 4. Bordi incompleti intorno al div
- 5. Perché ruby-debug dice "I fotogrammi salvati possono essere incompleti"
- 6. Come gestire i file IDE in un repository git?
- 7. Come gestire i download di file utilizzando JavaFX 2.0 WebEngine
- 8. Come gestire i riferimenti ai file VB6 .vbp che cambiano
- 9. Come modificare git add per gestire i file cancellati?
- 10. Come gestire i file con lo stesso nome in Wix?
- 11. come gestire i file di accesso .mdb con python
- 12. Come gestire i file su un dispositivo portatile MTP?
- 13. Come gestire ~ nei percorsi file
- 14. Come gestire i progetti personali
- 15. Come gestire i riferimenti circolari?
- 16. Git - come gestire i symlink
- 17. Come ottenere i file mainBundle per iPhone
- 18. Come ottenere i nomi dei file?
- 19. Come ottenere i metadati dai file mp3
- 20. Sanitizza HTML e chiude tag incompleti
- 21. Come ottenere un file batch per gestire gli spazi nei nomi dei file?
- 22. implementazione grafico/albero con tipi incompleti
- 23. jQuery autocomplete - Come gestire i dati aggiuntivi?
- 24. Come gestire i principali aggiornamenti framework/dipendenza?
- 25. Come gestire i messaggi WndProc in WPF?
- 26. Come gestire i dati obsoleti in REST?
- 27. Come gestire i caratteri speciali nel markdown?
- 28. Come gestire i percorsi lunghi in Bash?
- 29. Come gestire? _escaped_fragment_ = per i crawler AJAX?
- 30. Come gestire i repository svn in xcode
È bello sapere, quale eccezione? –