Domanda

Ho un'applicazione Java che controlla una cartella per i file XML in arrivo. Quando viene rilevato un nuovo file, devo testare il file che non è attualmente in fase di aggiornamento e viene chiuso. Il mio pensiero è di utilizzare File. canWrite () per testarlo. C'è qualche problema con questo? È un buon modo per provare che un file è stato completamente scritto?

Altre idee che sto lanciando sono:

  • Analizza il file XML in arrivo ed esegui il test che il tag di chiusura è lì.
  • Verifica il carattere EoF.

Non sono sicuro che nessuno di questi metodi gestirà tutti gli scenari.

È stato utile?

Soluzione

No, canWrite non è adatto a questo scopo. In generale il file sarà scrivibile anche se sta scrivendo un altro processo.

È necessario un protocollo di livello superiore per coordinare il blocco. Se prevedi di utilizzare questo codice su un'unica piattaforma, potresti essere in grado di utilizzare Funzione FileLock di NIO . Ma leggi attentamente la documentazione e nota che su molte piattaforme il blocco è solo consultivo.

Un altro approccio consiste nel fare in modo che un processo scriva il file con un nome che il processo non riconoscerà, quindi rinominare il file con un nome riconoscibile al termine della scrittura. Sulla maggior parte delle piattaforme, l'operazione di ridenominazione è atomica se l'origine e la destinazione hanno lo stesso volume del file system. La modifica del nome potrebbe utilizzare un'estensione di file diversa o persino spostare il file da una directory a un'altra (sullo stesso volume).

Dato che in questo caso stai lavorando esclusivamente con XML, la ricerca di un tag vicino funzionerebbe, ma non è infallibile: cosa succede se ci sono commenti dopo il markup finale, o lo scrittore o semplicemente non scrive un XML valido ?

Cercare l'EOF non funzionerà. Ci sarà sempre un EOF, anche quando lo scrittore ha appena aperto il file e non ha ancora scritto nulla. Se così non fosse, la cosa più semplice sarebbe consentire al lettore di iniziare l'analisi non appena viene visualizzato il file; si bloccherebbe fino a quando lo scrittore non chiuderà il file. Ma il file system non funziona in questo modo. Ogni file ha una fine, anche se al momento alcuni processi lo stanno spostando.

Altri suggerimenti

Inoltre, se fai un controllo seguito da una scrittura, hai una condizione di gara. Lo stato potrebbe cambiare tra il segno di spunta e la scrittura. A volte è meglio provare a fare ciò che vuoi e gestire gli errori con grazia. forse un meccanismo di tentativi n-tentativo con un tempo di ritardo di fallback aumentato.

O ridefinisci il tuo test. In questo caso, potresti provare che la dimensione del file non è cambiata per un certo periodo di tempo prima di elaborarla.

Un'altra opzione è quella di dividere il codice in due, potresti avere un altro thread - forse un'attività al quarzo - responsabile dello spostamento dei file finiti in una directory diversa che il tuo codice principale elabora.

Una cosa che sembra funzionare in Windows è questa - Crea un oggetto File () che rappresenta il file in questione (usando il costruttore con nome file completo) - Crea un secondo oggetto file identico, allo stesso modo. - Prova firstFile.renameTo (secondFile)

Questo esercizio di ridenominazione fittizia sembra riuscire con i file che non sono aperti per la modifica da un'altra app (ho testato con Word), ma fallisce se sono aperti.

E come nw nomefile = il vecchio nomefile non crea nessun'altra opera.

Per quanto ne so, non c'è modo di sapere se un altro processo ha attualmente un handle aperto su un file da Java. Un'opzione è utilizzare FileLock classe dal nuovo io. Questo non è supportato su tutte le piattaforme, ma se i file sono locali e il processo di scrittura del file collabora, dovrebbe funzionare per qualsiasi piattaforma che supporti i blocchi.

Se controlli sia il lettore che lo scrittore, una potenziale tecnica di blocco sarebbe quella di creare una directory di blocco - che di solito è un'operazione atomica - per la durata del processo di lettura e scrittura. Se si adotta questo tipo di approccio, è necessario gestire il potenziale fallimento di un processo con conseguente "sospensione". directory di blocco.

Come menzionato Cheekysoft, i file non sono atomici e non sono adatti per il blocco.

Se non controlli lo scrittore, ad esempio se viene prodotto da un demone FTP, le opzioni migliori sono la tecnica di rinomina o il ritardo per la tecnica dell'intervallo di tempo.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top