2009-03-27 9 views
9

Ho un'applicazione in cui a volte ho bisogno di leggere dal file in fase di scrittura e di conseguenza viene bloccato. Come ho capito dagli altri questions dovrei prendere IOException e riprovare finché non riesco a leggere.come aspettare il rilascio di un filelock

Ma la mia domanda è come faccio a sapere con certezza che il file è bloccato e che non è un'altra IOExcetpion che si verifica.

risposta

5

Quando si apre un file per la lettura.NET sarà ad un certo punto cercare di creare un handle di file utilizzando la funzione CreateFile API che imposta il error code che può essere utilizzato per vedere perché non è riuscito:

const int ERROR_SHARING_VIOLATION = 32; 
try 
{ 
    using (var stream = new FileStream("test.dat", FileMode.Open, FileAccess.Read, FileShare.Read)) 
    { 
    } 
} 
catch (IOException ex) 
{ 
    if (Marshal.GetLastWin32Error() == ERROR_SHARING_VIOLATION) 
    { 
     Console.WriteLine("The process cannot access the file because it is being used by another process."); 
    } 
} 
+2

Sfortunatamente, non si può essere certi che l'errore Win32 sia stato effettivamente causato dalla chiamata API CreateFile. Questo potrebbe cambiare in un'altra versione del framework. Per essere sicuro, chiama l'API Win32 tu stesso. –

0

per leggere i dati si può fare:

usando (FileStream fs = new FileStream (nome del file, FileMode.Open, FileAccess.Read, FileShare.ReadWrite | FileShare.Delete)) {.. ..}

e di salvare in un file:

usando (FileStream fs = new File Stream (fileName, FileMode.Append, FileAccess.Write, FileShare.Read | FileShare.Delete)) {...}

Bandiere al termine dei costruttori descrive cosa altro processo può fare con il file. E 'bene, naturalmente, se controlli sia scrivere e leggere ...

0

è possibile confrontare contro il tipo IOException per controllare e vedere se non è qualcosa d'altro

Come

if (ex is FileNotFoundException) 

Si potrebbe voler cercare la guida su System.IO. Molte delle eccezioni in quella classe ereditano da IOException. Al di fuori del controllo per vedere se si tratta di un altro tipo di eccezione potrebbe essere necessario cercare nel messaggio della descrizione o si potrebbe cercare di effettuare una chiamata API Win32 in shell32.dll. Ci può essere una funzione in là per verificare se un file è bloccato.

Inoltre, se è assolutamente necessario attendere, è possibile utilizzare il ciclo, ma se si desidera eseguire altre azioni durante l'attesa, utilizzare un thread asincrono.

0

vuoi dire si sono entrambi la lettura e la scrittura nel file? O che un'applicazione esterna ci sta scrivendo.

Se stai facendo la lettura e la scrittura, suppongo che lo stai facendo su thread diversi, nel qual caso dai un'occhiata alla classe ReaderWriteLock che farà questa gestione per te e ti consentirà di fornire timeout.

http://msdn.microsoft.com/en-us/library/system.threading.readerwriterlock.aspx

Altrimenti tutto quello che dovete fare è aprire il file in modalità di sola lettura. Quindi non dovresti avere problemi:

fileStream = new FileStream(fileName, FileMode.Open, FileAccess.Read)); 
4

C'è una discussione utile su google groups che si dovrebbe davvero leggere. Una delle opzioni è vicina a quella di Darin; tuttavia, per garantire l'errore win32 corretto, dovresti chiamare tu stesso l'API win32 OpenFile(), altrimenti non sai quale errore stai recuperando.

Un altro è analizzare il messaggio di errore: non funzionerà se l'applicazione viene eseguita in un'altra lingua.

Una terza opzione consiste nell'hackare all'interno della classe di eccezioni con la riflessione per calcolare l'HRESULT effettivo.

Nessuna alternativa è davvero così attraente: la gerarchia IOException trarrebbe vantaggio da alcune altre sottoclassi IMHO.