Search code examples
c#memory-mapped-filesmemory-mapping

Enable writing to file that is mapped to memory


I will like to use a memory mapped file to virtualize opening a file on windows when that file is realy on the internet.

So I create the memory mapped file as:

// data that we write to the file. we will get this a tcp
var data = System.Text.Encoding.UTF8.GetBytes("Hello World");

var fileStream = new FileStream("SomeFile.txt", FileMode.Create);

using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024, 
    MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
{
    var viewStream = memoryMapped.CreateViewStream();                
    viewStream.Write(data, 0, data.Length); // write hello world                                
}

And I can read from it on windows but not save it:

enter image description here

Note how I was able to open the file (meanwhile the data was on memory and not the hard disk) but the moment I tried saving changes I was not able. So my question is: How could I enable saving changes to that file and be just changing the content in memory of the memory mapped file without actually trying to save anything to disk.


Solution

  • You need to specify the sharing mode when creating the file stream.

    var fileStream = 
        new FileStream("SomeFile.txt", FileMode.Create, 
                       FileAccess.ReadWrite, FileShare.ReadWrite);
    

    Also, you need to dispose of your FileStream when done, e.g. with a using statement.

    UPDATE

    It worked just fine for me. Using Notepad I had to manually re-open the file, but I could update it while Notepad had it open (Notepad just did not check for external modifications).

    Side note: The code writes a bunch of NUL (0x00) bytes to the end of the file. You'll probably want to look into that.

    Here's the exact code I used (note the local path to C:\Temp. Change if needed):

        static private void WriteMMF()
        {
            // data that we write to the file. we will get this a tcp
            var data = System.Text.Encoding.UTF8.GetBytes("Hello World 2");
    
            using (var fileStream = new FileStream(@"C:\Temp\SomeFile.txt", FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
            using (MemoryMappedFile memoryMapped = MemoryMappedFile.CreateFromFile(fileStream, "MapName", 1024,
                MemoryMappedFileAccess.ReadWrite, new MemoryMappedFileSecurity(), HandleInheritability.Inheritable, true))
            {
                var viewStream = memoryMapped.CreateViewStream();
                viewStream.Write(data, 0, data.Length); // write hello world                                
            }
        }
    
    
        static void Main(string[] args)
        {
            Console.WriteLine("Writing MMF");
    
            WriteMMF();
    
            Console.WriteLine("Done.  Press a key.");
            var ch = Console.ReadKey();
    
            return;
        }