2011-10-24 17 views
10

Voglio creare un file SOLO se non esiste già.
Un codice simile:Crea un file solo se non esiste

if (!File.Exists(fileName)) 
{ 
    fileStream fs = File.Create(fileName); 
} 

Lasciare aperto per una gara condizionata in caso verrà creato il file tra il "se" al "creare".

Come posso evitarlo?

EDIT:
serrature non possono essere utilizzati qui perché è un diversi processi (più istanze della stessa applicazione).

+0

utilizzando try {} catch {}? – ojlovecd

+0

stessa applicazione? mutex? –

risposta

9

La risposta di Kristian Fenn era quasi ciò di cui avevo bisogno, solo con un diverso FileMode. Questo è quello che stavo cercando:

FileStream fs = new FileStream(fileName, FileMode.CreateNew); 
1

Se i tentativi contendenti di creare il file sono nello stesso processo, è possibile utilizzare un'istruzione lock attorno al codice per evitare conflitti.

In caso contrario, è possibile che occasionalmente si verifichi un'eccezione quando si chiama File.Create. Gestisci appropriatamente quell'eccezione. Verificare se il file esiste prima della creazione è probabilmente consigliabile anche se si sta gestendo un'eccezione quando il file esiste perché un'eccezione generata è relativamente costosa. Non sarebbe consigliabile solo se la probabilità della condizione di gara è bassa.

+1

Spero che tu non scriva nessuno dei software che uso. Sicurezza garantita al di sopra di congetture, per favore. – reinierpost

19

È inoltre possibile utilizzare

FileStream fs = new FileStream(fileName, FileMode.OpenOrCreate); 

Tuttavia, si dovrebbe guardare in blocco filo come se più di un thread tenta di accedere al file probabilmente otterrete un'eccezione.

+0

MSDN non indica se tale funzione di costruzione è protetta da thread, pertanto è consigliabile fare attenzione in un ambiente con multithreading. –

+1

Due thread che lo tentano contemporaneamente otterranno gli stessi risultati di ['CreateFile'] (http://msdn.microsoft.com/en-us/library/aa363858 (VS.85) .aspx) (come' FileStream' ' s constructor è un wrapper su Win32) chiamato in concomitanza - vincerà un thread. A quanto ho capito, a livello di kernel questa è una singola operazione: un thread non verrà creato mentre l'altro lo aprirà. – Richard

+0

Grazie Richard, buono a sapersi. –

1

Per prima cosa bloccare o monitorare. Immettere o TryEnter API per bloccare la parte del codice. In secondo luogo è possibile utilizzare l'API FileStream con l'API FileMode.OpenOrCreate. Se il file esiste, lo usa o lo crea.

3

Questa non è una soluzione migliore. Notare anche lo using(var stream...) Utilizzarlo per chiudere lo stream per evitare Eccezioni IO.

if (!File.Exists(filePath)) 
{ 
    using (var stream = File.Create(filePath)) { } 
}