You might get an exception that says “The process cannot access the file C:\bla\bla.bin because it is being used by another process” when trying to read all bytes at once using File.ReadAllBytes(). While it is arguable if you should be reading an entire file into memory at once, but in here we’ll assume you do have a good reason. Anyways, so why does the error occur? That’s what I want to talk about.
File.ReadAllBytes() function is written such that it uses a call like the following to instantiate a FileStream:
FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read)
How do I know this? Well, there’s a mass-downloader tool for downloading .NET 2.0 code that Microsoft made available a couple of months ago. Before that there was Reflector.
Notice that the FileShare is specified as Read. That means if you have another piece of code writing to the same file at the same time, you will get an error even if the other piece of code created the FileStream by specifying the share mode as “ReadWrite” like so:
FileStream fs = new FileStream(path, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)
So what’s the solution? Well we need to open the FileStream while reading with a share mode of “ReadWrite” instead of “Read”. You cannot change what ReadAllBytes does. So if you need functionality like that, you are going to have to implement a similar function on your own.
Here’s how you can do that:
public static byte[] ReadAllBytes(String path) { byte[] bytes; using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { int index = 0; long fileLength = fs.Length; if (fileLength > Int32.MaxValue) throw new IOException("File too long"); int count = (int)fileLength; bytes = new byte[count]; while (count > 0) { int n = fs.Read(bytes, index, count); if (n == 0) throw new InvalidOperationException("End of file reached before expected"); index += n; count -= n; } } return bytes; }
Rulas
August 26, 2008
Nice try with reflector, but what if you try to close your stream at the end of your method, something like this:
fs.Close()
Hope this help
Korayem
November 7, 2008
Man, thank you for sharing this snippet.
I am developing a VSTO addin that uploads the current open file. It required the built-in File.ReadAllBytes() which obviously threw an error as File.ReadAllBytes() attempts to close the file after reading it’s contents.
Now I am using YOUR method which works flawlessly.
PS: I shared your method as an alternative solution to the proposed ones here:
http://social.msdn.microsoft.com/Forums/en-US/vsto/thread/84f1ac3f-f078-4087-a627-351d6bb57173/
Ricardo
August 19, 2009
Thanks for the snippet. Works like a charm
Floooo49
May 6, 2011
Very helpful thanks
DongRaeGu
July 24, 2011
Thanks works fine.
What is the exact reason ReadWrite access is needed though, even though you just want to read?