Challenge: Have you ever faced a problem wherein two processes are accessing the same file, one is reading it and the other one is writing in it and one of them (mostly the reader process) gives error that the file is in use by another process? Well, I faced it multiple times in some small tools that I made, and I faced it even in a writer process, when say the status file between multiple processes was kept open, then I found this error in the Application User Logs Concept:Well, first of all, we need to understand some basic concepts, when dealing with Files. To read and write files, we make use of the FileStream Class. Next, there are Enumerators defined that contain specific flags, which we need to select appropriately in the constructor of FileStream Class, so that the FileStream Object will act accordingly. The Enumerators are: 1. FileAccess
- Read – Gives read access to the file.
- ReadWrite – Gives both Read as well as Write access to the file.
- Write – Gives Write access to the file.
2. FileMode
- Append – If the file exists, opens it, moves to the end of it and adds there, else creates a file.
- Create – Creates a new file. In case such a file already exists, then overwrites it.
- CreateNew – Creates a new file. In case such a file already exists, throws in IO Exception.
- Open – Opens the file, throws exception if the specified file does not exist.
- OpenOrCreate – Opens the file if it already exists, else creates a new one.
- Truncate – Opens the specified file, and once it is opened, specifies to the OS to remove all the contents of that file so that its size is zero.
3. FileShare
- None – File Cannot be Shared
- Write – Allow opening File for Writing
- Read – Allow opening File for Reading
- ReadWrite – Allow opening File for Reading or Writing
Now, what to do in case you have two processes doing the write and read operations concurrently?? First of all, FileMode doesn’t matter at all! Next, what matters is the FileShare given to both the processes, you should give ReadWrite Share to both — The reader as well as the writer process — so that they are at the same level. And last, is the FileAccess — the reader should be given Read Access while the writer be given either Write Access or ReadWrite Access(in case you use something to append in a file, better use ReadWrite Access.) — For me, FileAccess ReadWrite worked the best.. you can try in your case and find you best suitable solution. Ok, enough of concept now, Lets look at some code. Sample Code:
[sourcecode language=”csharp”]
static void Main(string[] args)
{
ThreadStart jobwrite = new ThreadStart(Writer);
Thread threadWrite = new Thread(jobwrite);
threadWrite = new Thread(jobwrite);
threadWrite.Name = "Write";
threadWrite.Start();
/////////
ThreadStart jobread = new ThreadStart(Reader);
Thread threadread = new Thread(jobread);
threadread = new Thread(jobread);
threadread.Name = "read";
threadread.Start();
threadWrite.Join();
threadread.Join();
Console.Read();
}
[/sourcecode]
— The Reader Process
[sourcecode language=”csharp”]
private static void Reader()
{
try
{
for (int i = 0; i < 1000; i++)
{
using (FileStream fs = File.Open("F:\\111.txt", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
{
StreamReader sr = new StreamReader(fs);
string str = sr.ReadToEnd();
sr.Close();
fs.Close();
Console.Write("Read: " + str + Environment.NewLine);
}
System.Threading.Thread.Sleep(10);
}
}
catch (Exception ex)
{
Console.Write("read" + ex.ToString());
Console.Read();
}
}
[/sourcecode]
— The Writer Process
[sourcecode language=”csharp”]
private static void Writer()
{
try
{
for (int i = 0; i < 1000; i++)
{
string status = i.ToString();
using (FileStream fs = File.Open("F:\\111.txt", FileMode.Create, FileAccess.Write, FileShare.ReadWrite))
{
byte[] bytes = Encoding.ASCII.GetBytes(status);
fs.Write(bytes, 0, bytes.Length);
fs.Close();
Console.Write("Write:" + status + Environment.NewLine);
}
System.Threading.Thread.Sleep(10);
}
}
catch (Exception ex)
{
Console.Write("write" + ex.ToString());
Console.Read();
}
}
[/sourcecode]
Credit: If you liked this article and got the solution for the problem that you were facing, then you must thank my friend and collegue YOGESH PATEL. I was thinking of writing this article since a long time, but did not write it because didnt want to make it a theoritical article. And this guy gave me a superb piece of code that you see above. Well, I gotto say one thing for Yogesh that he is the fastest developer I have ever seen. Once he sits with his headphones/easrphones on, some miracles — solutions to some weirdest problems — come out of his development machine. Happy Concurrent File Accessing!
Amazing blog, and an interesting article!
Thanks Gerrard!
Keep referring and keep sharing! 🙂
Thanks Gerrard, Keep referring and keep sharing!
Sincerely,
Varun Shringarpure
nice code bro 😀 you save me from big trouble 😀 thumbs up 😀
Glad to know it helped! 🙂
Happy to know that Pasindu.
Thanks for sharing that with me. 🙂
Regards,
Varun Shringarpure
Thanks! I had forgotten how to open files in this mode and File.Create won’t let you adjust these options.
Thankyou!
Greetings Varun (and YOGESH PATEL)! I searched the Web far and wide, to find out if i could access one single file with two apps (one read and one write), and kept getting references to MS Access, How to open two excel files, etc. Finally, i came across YOUR article which explained it PERFECT! Thank you YOGESH, for your beautifully connected brain cells, and you Varun, for the wisdom of sharing! Just wanted to let you both know, you made a difference to this amateur in Virginia!
Larry, It feels great reading that comment from you. Thank you for letting us know!
This old post still works as a charm!
Glad that it helps. 🙂
Very helpful !!!