2009-04-03 5 views
17

Cosa succede quando si aprono contemporaneamente due (o più) FileOutputStreams sullo stesso file?Scrittura simultanea di file in Java su Windows

Il Java API dice questo:

Alcune piattaforme, in particolare, permettono un file da aprire per la scrittura di un solo FileOutputStream (o altro oggetto file-scrittura) alla volta.

Suppongo che Windows non sia una piattaforma di questo tipo, perché ho due thread che leggono alcuni file di grandi dimensioni (ognuno uno diverso) e lo scrivono sullo stesso file di output. Non viene generata alcuna eccezione, il file viene creato e sembra contenere blocchi da entrambi i file di input.

domande collaterali:

  • Questo è vero per Unix, troppo?
  • E poiché voglio che il comportamento sia lo stesso (in realtà voglio che un thread scriva correttamente e l'altro sia avvisato del conflitto), come posso determinare che il file sia già aperto per la scrittura?

risposta

16

Non esiste un modo affidabile e multipiattaforma per ricevere una notifica passiva quando un file ha un altro writer —, ad esempio un'eccezione se un file è già aperto per la scrittura. Ci sono un paio di tecniche che ti aiutano a controllare attivamente questo, comunque.

Se più processi (che possono essere un misto di Java e non Java) potrebbero utilizzare il file, utilizzare FileLock. Una chiave per utilizzare con successo i blocchi di file è ricordare che sono solo "di consulenza". Il blocco è garantito per essere visibile se lo controlli, ma non ti impedirà di fare cose sul file se lo dimentichi. Tutti i processi che accedono al file devono essere progettati per utilizzare il protocollo di blocco.

Se un singolo processo Java funziona con il file, è possibile utilizzare gli strumenti di concorrenza incorporati in Java per farlo in modo sicuro. È necessaria una mappa visibile a tutti i thread che associa ciascun nome di file all'istanza di blocco corrispondente. Le risposte a a related question possono essere facilmente adattate allo scopo con gli oggetti File o canonical paths in file. L'oggetto lock potrebbe essere un FileOutputStream, un altro wrapper attorno allo stream o uno ReentrantReadWriteLock.

4

Sarei cauto nel lasciare che il sistema operativo determini lo stato del file per voi (poiché dipende dal sistema operativo). Se si dispone di una risorsa condivisa, limitare l'accesso ad essa utilizzando Re-entrant lock

L'utilizzo di questo blocco significa che un thread può ottenere la risorsa (file) e scrivere su di esso. Il thread successivo può verificare se questo blocco è trattenuto da un altro thread e/o bloccare indefinitamente fino a quando il primo thread lo rilascia.

Windows (penso) limiterebbe due processi che scrivono sullo stesso file. Non credo che Unix farebbe lo stesso.

+0

Ma non voglio bloccare ogni volta che scrivo, voglio bloccare, se qualcuno sta già scrivendo sul file che voglio scrivere. In realtà, non voglio affatto bloccare. Voglio dire al secondo thread che non può scrivere e lasciare che il cliente decida su ulteriori azioni. –

+0

CHeck that lock API. Sarai in grado di ispezionare il lucchetto per determinare se qualcuno lo ha già bloccato (cioè non bock) e poi decidere cosa fare –

1

Se i 2 thread di cui si sta parlando si trovano nella stessa JVM, è possibile che una variabile booleana sia accessibile da entrambi i thread.

1

Unix consente ai writer contemporanei di eseguire lo stesso file.

Non si dovrebbe tentare di scrivere sullo stesso file più di una volta. Se sei hai un difetto di progettazione.