Reading While Writing a File

mskeel

Well-known member
Joined
Oct 30, 2003
Messages
913
Location
Virginia, USA
Im having a hard time finding documentation to figure out how read/write locks work in .Net. The basic gist is that I have a log file that is constantly being written to and I want to be able to read the log file and determine meaningful statistics without having to stop the process that is writing the file. It is my understanding that a file can have many readers but only one writer. Does that hold true for .Net?

Im pretty sure the standard StreamWriter and StreamReader both get exclusive locks for reading and writing which means I cant use either of those to write or read because it will cause one application to barf depending on who gets the write lock first. I think that means I have to use a regular FileStream to read and write the file so I can have more fine grained control over what locks are in place.

The problem is I cant figure out how to set it all up. Heres what I am currently trying.
Code:
Dim writer as FileStream = File.Open(pathToFile, FileMode.Open, FileAccess.ReadWrite)
writer.Seek(0, SeekOrigin.End)  I want to append but it looks like FileMode.Append makes the file exclusive

 ...

Dim reader As FileStream = File.Open(pathToFile), FileMode.Open, FileAccess.Read) Throws an exception: File being used by another process.

 Ill shut everything down later...

I cant seem to get my file locking right to allow this to happen. Any help would be greatly appreciated.
 
There is another overload on the constructor of the FileStream that also allows you to specify the FileShare option. This can be (amonst others) None, Read, ReadWrite, Write.

I dont know what the default value is, but perhaps by specifying ReadWrite share whenever you wish to do something with the file, other access to the file is also allowed.
 
Got it, thanks for the assist.

Thanks, Wile. I completely overlooked that constructor. It turns out (thankfully) that you can still use a StreamReader/StreamWriter, the trick is that you have to pass a stream that has the permissions set the way you want them.

Heres what I ended up doing to get everything to work the way I wanted them to:
Code:
Dim sw As StreamWriter = New StreamWriter(File.Open(pathToFile, FileMode.Append, FileAccess.Write, FileShare.Read))

 ...

Dim sr As StreamReader = New StreamReader(File.Open(pathToFile, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))

 Shut both streams down later on.

I found that it was not sufficient to just open the writer with read, but the reader later on, also had to be opened read/write otherwise an exception was thrown (file being used by another process). The thing that really made all of this hard was the name of those last two arguments in the constructor: FileAccess and FileShare, both of which have Read, ReadWrite, and Write options and both of which could mean about the same thing, at least to me. It was just a little confusing, but its all figured out now.

Thanks, Wile, you are life saver.
 
Back
Top