views:

44

answers:

2

Is there a way to promoting a Read-Only FileStream to Read-Write? I am looking for functionality similar to the Win32 SDK function ReOpenFile.

A: 

You can't.

Why do you open it readonly in the first place? Why don't you just open a new FileStream? You do not even have to close the old one, provided that the FileShare is set correctly.

codymanix
Its about operating with the minimal amount of permissions. Some users will not have write access, while others do. Since all need to read, I can open in read-only mode. When the few that need to write try, I can check the CanWrite property, and then escalate for that operation only. Opening another stream will cause two views on the same data, with only the permissions different. This means I also have to maintain the two streams, and add logic for that throughout the system or build a class to contain two streams with differing permissions.
David B
One more point, the OS supports this. This limitation is purely in the .NET BCL. See ReOpenFile (http://msdn.microsoft.com/en-us/library/aa365497(VS.85).aspx).
David B
You can develop your own from stream class which is able to switch between read and write mode by maintaining multiple streams internally. This way you can abstract this detail away.
codymanix
+1  A: 

Here you go. Uses a bit of pInvoke Interop goodness (badness), but it'll do it. I've skimped and threw in some magic constants for the access and sharemode parameters, so feel free to encapsulate that.

private static void Main()
{
    using (FileStream fs = new FileStream(@"..\..\Program.cs", FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
    {
        using (TextReader tr = new StreamReader(fs))
        {
            Console.WriteLine(tr.ReadToEnd());

            using (FileStream fs1 = new FileStream(ReOpenFile(fs.SafeFileHandle, 3, 3, 0), FileAccess.ReadWrite))
            {
                fs1.Seek(0, SeekOrigin.End);
                using (TextWriter tw = new StreamWriter(fs1))
                {
                    tw.WriteLine("/* this should be all right */");
                }
            }
        }
    }
}

[DllImport("kernel32", SetLastError = true)]
private static extern SafeFileHandle ReOpenFile(SafeFileHandle hOriginalFile, uint dwAccess, uint dwShareMode, uint dwFlags);
Jesse C. Slicer
This is what I was thinking, but was concerned that FileStream would rebuffer the data, and the two would get out of sync. I am also concerned that the use of interop will require a higher permission than available. I will give it a try.
David B
This worked. Thanks! I added the following code after the innermost using statement to prove the FileStream (fs) and TextReader (tr) are still reusable: // seek to the beginning and try to read again fs.Seek(0, SeekOrigin.Begin); Console.WriteLine("*** Reading Again ***"); Console.WriteLine(tr.ReadToEnd());Thanks
David B