Using memory mapped files with C#

.Net Framework 4.0 introduces memory mapped files. Memory mapped files are useful when you need to do in-memory data manipulation and your data structures are large. For large in-memory data the performance of memory mapped file is the best. It is much faster than MemoryStream. And like files on hard disc, memory mapped files can be shared between different programs. MemoryMappedFile and other classes for memory mapped files can be found from System.IO.MemoryMappedFiles namespace.

Now let’s see the example that contains two applications: one of them is primitive server that creates and holds memory mapped file and the other is simple client that reads that file. In the end of the posting you can find download link for example Visual Studio 2010 solution.

MemoryMappedFile server

Our server, as I said before, is primitive. It creates memory mapped file and writes some bytes to our file. Then it starts waiting key press from user to release resources and exit. The code of server is here.

static void Main(string[] args)
{
   
Console.WriteLine("Memory mapped file server started"
);

   
using (var file = MemoryMappedFile.CreateNew("myFile", int
.MaxValue))
    {
       
var bytes = new byte
[24];
       
for (var
i = 0; i < bytes.Length; i++)
            bytes[i] = (
byte
)(65 + i);

       
using (var
writer = file.CreateViewAccessor(0, bytes.Length))
        {
            writer.WriteArray<
byte
>(0, bytes, 0, bytes.Length);
        }
       
Console.WriteLine("Run memory mapped file reader before exit"
);
       
Console.WriteLine("Press any key to exit ..."
);
       
Console.ReadLine();
    }
}

MemoryMappedFile reader

The client project opens memory mapped file and reads bytes that server wrote there. I hope you notice that I hard coded the count of bytes that reader reads from memory mapped file. The point is simple – we are accessing memory mapped file directly without any contracts for file structure. In reality there will be some API that you use to manager memory mapped file in your application.

static void Main(string[] args)
{
   
Console.WriteLine("Memory mapped file reader started"
);

   
using (var file = MemoryMappedFile.OpenExisting("myFile"
))
    {
       
using (var
reader = file.CreateViewAccessor(0, 24))
        {
           
var bytes = new byte
[24];
            reader.ReadArray<
byte
>(0, bytes, 0, bytes.Length);

           
Console.WriteLine("Reading bytes"
);
           
for (var
i = 0; i < bytes.Length; i++)
               
Console.Write((char)bytes[i] + " "
);

           
Console.WriteLine(string
.Empty);
        }
    }

   
Console.WriteLine("Press any key to exit ..."
);
   
Console.ReadLine();
}

Now run server (MemoryMappedFileCreate) and after that the client (MemoryMappedFileRead). Server creates new memory mapped file and writes there 24 bytes of characters. Client then reads these bytes and writes them to console.

To find out more about memory mapped files feel free to read MSDN Utopia blog entry Working with memory mapped files in .NET 4.

Gunnar Peipman

Gunnar Peipman is ASP.NET, Azure and SharePoint fan, Estonian Microsoft user group leader, blogger, conference speaker, teacher, and tech maniac. Since 2008 he is Microsoft MVP specialized on ASP.NET.

    14 thoughts on “Using memory mapped files with C#

    • June 24, 2009 at 3:13 pm
      Permalink

      Do you know if I can try these examples on VS2008,
      I have installed the Net framework 4 beta 1.

      Thank you

    • July 3, 2009 at 7:20 am
      Permalink

      Thanks for comments, guys! :)

      Aaron: I made no tests with different boundary values. Also I made no tests in 64bit environment.

      Cameron: AFAIK you cannot use .Net Framework 4 Beta 1 features in VS2008.

    • August 5, 2009 at 8:37 pm
      Permalink

      Console based examples worked great. If I put inside a windows form, the client works fine, but the server doesn’t. Am I missing something here? I used the VB code provided but wrapped in a form.

    • August 5, 2009 at 8:55 pm
      Permalink

      Hello Bill!

      Did your VB client worked okay against console based server?

    • August 6, 2009 at 12:02 am
      Permalink

      Thanks for responding.

      Yes, both versions of the VB client (console-based and windows-based) worked, but only for the console-based server. Both failed with a “cannot find file” exception when I used the windows-based server.

    • August 6, 2009 at 5:53 am
      Permalink

      I was not able to find a reason for this behavior. Did you try to run both of them under same privileges? Did you try to run them under admin privileges?

    • August 6, 2009 at 4:19 pm
      Permalink

      Thanks for asking. All were run under the same privileges. Here is the code:
      Imports System.IO.MemoryMappedFiles
      Using file = MemoryMappedFile.CreateNew(“myFile”, Integer.MaxValue)
      Dim bytes = New Byte(23) {}
      For i = 0 To bytes.Length – 1
      bytes(i) = CByte(i + 65)
      Next
      Using writer = file.CreateViewAccessor(0, bytes.Length)
      writer.WriteArray(Of Byte)(0, bytes, 0, bytes.Length)
      End Using
      End Using

    • August 6, 2009 at 7:04 pm
      Permalink

      Also, I have Admin privilege on my computer (XP-32) and run my programs in that mode.

    • August 6, 2009 at 9:14 pm
      Permalink

      Hmm… seems like I have to handle this problem over to .Net development team.

    • August 6, 2009 at 11:43 pm
      Permalink

      Thanks, DigiMortal. I hope it’s not me. Good luck!

    • July 22, 2011 at 4:20 pm
      Permalink

      isnt it because the writer is getting disposed? your method exits right after creating the writer etc…

    • February 3, 2012 at 4:31 am
      Permalink

      I am trying to use the MMF feature between a Winform application and an ASP.net program. The idea being the WinForm app creates and populates the MMF and the ASP.net Web program displays the data from the MMF.
      However the ASP program returns “FileNotFound” Error. This seems to be some sort of permissions between the two processes and they are not able to see the MMF between them. Any ideas?

    • November 18, 2016 at 5:26 pm
      Permalink

      It would be interesting to know how this works internally.
      E.g. how the int.MaxValue affects this?
      Does it allocate this amount of memory beforehand?
      What happens if you try to write more than that?
      Can yo rewind the file and overwrite old data to avoid it grow over time?

    Leave a Reply

    Your email address will not be published. Required fields are marked *