Ho un problema di condivisione file in cui il mio processo sta tentando di leggere un file di registro mentre è ancora aperto da NLog. Nel diagnosticare il problema, ho trovato qualcosa di sorprendente. Quanto segue non riesce:La condivisione di file non funziona come previsto
using (var fileStream1 = new FileStream("test.file", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fileStream2 = new FileStream("test.file", FileMode.Open, FileAccess.Read, FileShare.Read))
{
}
Il secondo FileStream
chiamata al costruttore fallisce con:
System.IO.IOException was unhandled
Message=The process cannot access the file 'c:\...\test.file' because it is being used by another process.
Source=mscorlib
StackTrace:
at System.IO.__Error.WinIOError(Int32 errorCode, String maybeFullPath)
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath)
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share)
Questo nonostante il fatto che il primo FileStream
indica la sua volontà di condividere la lettura. Quello che ho trovato ancora più sorprendente è che questo funziona:
using (var fileStream1 = new FileStream("test.file", FileMode.Append, FileAccess.Write, FileShare.Read))
using (var fileStream2 = new FileStream("test.file", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
}
Uhm, sì, chiedendo accesso più quando si apre il secondo flusso in realtà bypassa il problema. Sono completamente sconcertato sul perché questo sia il caso, e posso solo supporre che io stia fraintendendo qualcosa. Ho letto i documenti dell'API, ma supportano il mio attuale modello mentale per come dovrebbe funzionare, contrariamente a come funziona.
Ecco alcune citazioni sostegno del docs:
Un utilizzo tipico di questa enumerazione è definire se due processi possono leggere simultaneamente dallo stesso file. Ad esempio, se un file è aperto e Read è specificato, altri utenti possono aprire il file per la lettura di ma non per la scrittura.
Ecco un altro gioiello:
Il seguente costruttore FileStream apre un file esistente e sovvenzioni accesso in sola lettura ad altri utenti (lettura).
FileStream s2 = new FileStream(name, FileMode.Open, FileAccess.Read, FileShare.Read);
Qualcuno può far luce su questo comportamento. Sto testando questo su .NET 4% Windows XP.
Grazie. Quindi questo equivoco è così diffuso che persino i documenti sono sbagliati/fuorvianti? –
Vuoi dire includere 'FileShare.Write' nel secondo stream, giusto? – rookie1024