tags:

views:

750

answers:

3

Is it possible to open a file in .NET with non exclusive write access? If so, how? My hope is to have two or more processes write to the same file at the same time.

Edit: Here is the context of this question: I am writing a simple logging HTTPModule for IIS. Since applications running in different app pools run as distinct processes, I need a way to share the log file between processes. I could write a complex file locking routine, or a lazy writer, but this is a throw away project so its not important.

This is the test code I used to figure out the process.

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Threading;

namespace FileOpenTest
{
    class Program
    {
        private static bool keepGoing = true;

        static void Main(string[] args)
        {
            Console.CancelKeyPress += new ConsoleCancelEventHandler(Console_CancelKeyPress);

            Console.Write("Enter name: ");
            string name = Console.ReadLine();
            //Open the file in a shared write mode
            FileStream fs = new FileStream("file.txt", 
                                           FileMode.OpenOrCreate, 
                                           FileAccess.ReadWrite, 
                                           FileShare.ReadWrite);

            while (keepGoing)
            {
                AlmostGuaranteedAppend(name, fs);
                Console.WriteLine(name);
                Thread.Sleep(1000);
            }

            fs.Close();
            fs.Dispose();
        }

        private static void AlmostGuaranteedAppend(string stringToWrite, FileStream fs)
        {
            StreamWriter sw = new StreamWriter(fs);

            //Force the file pointer to re-seek the end of the file.
            //THIS IS THE KEY TO KEEPING MULTIPLE PROCESSES FROM STOMPING
            //EACH OTHER WHEN WRITING TO A SHARED FILE.
            fs.Position = fs.Length;

            //Note: there is a possible race condition between the above
            //and below lines of code. If a context switch happens right
            //here and the next process writes to the end of the common
            //file, then fs.Position will no longer point to the end of
            //the file and the next write will overwrite existing data.
            //For writing periodic logs where the chance of collision is
            //small, this should work.

            sw.WriteLine(stringToWrite);
            sw.Flush();
        }

        private static void Console_CancelKeyPress(object sender, ConsoleCancelEventArgs e)
        {
            keepGoing = false;
        }
    }
}
A: 

Not possible. Learn about how files are read/written to disc.

Edit: Since all the downvotes, I guess I'll explain a little more. It is absolutely impossible for more than one process to write to the same file at the same exact time. When one process is writing, the file will normally be unavailable to other writers, meaning that the other processes would have to wait until the file is no longer being written to by the first process.

hmcclungiii
I believe the question writer wants to actually allow reads while he writes, rather than multiple writers.
Jeff Yates
"My hope is to have two or more processes write to the same file at the same time." Ya?
hmcclungiii
+6  A: 

Use the FileShare enumeration when opening the file using File.Open. Specifically, use FileShare.ReadWrite.

David Morton
Even with the FileShare enumeration, the same file cannot be written to by more than one process at a time.
hmcclungiii
Sure it can. Just did it. :)
David Morton
+2  A: 

The FileStream class has a constructor that takes several options including FileShare

new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite);
Rob McCready