Memory Mapped Files: are we doing it? [Kit George]

Memory Mapped Files: are we doing it? [Kit George]

  • Comments 3

Gheorghe Marius asked this question:

Question: Are there any plans to add support for memory mapped files in Whidbey ? If no...why ?

The answer is no Gheorghe. The why comes down to priorities, there simply wasn't enough interest in the feature at the point we were deciding what makes it into Whidbey, and what doesn't. We have become aware recently of the demand for this item, and we will be exploring it for the near future after Whidbey.

  • Take a look at the implementation of memory mapped files in the Caching Application Block.
  • Then I have a question based on this. An MMF would allow me some interesting ways to copy data from files into structures using Marshalling that might prove cool. However, I'm interested in a *safe* way to quickly map binary file data directly to CLR structures that is a bit more functional. For instance:

    An MP3 ID3v1 tag is 128 bytes and located at the end of a file. Currently, the only way to load up an ID3v1 tag in managed code (that I know of) is to parse the byte values into my structure by hand. This takes a long time and requires a lot of calls to APIs to get pieces of data, or it requires I operate over a byte and piece together bytes to form ints, etc...

    Will there be a functional, or is there an easier way to quickly map an ID3 tag from the 128 bytes at the end of the file into a managed structure?
  • What you're asking for is fundamentally unsafe. To get away from your somewhat slow byte munging form, you want to use some sort of pointer casting or pointer arithmetic. You can do this by defining a value type of the appropriate size, marking it with sequential layout, then casting a byte* to a pointer to that data type. This has some big caveats: The data in the file must be aligned properly with your structure, you must worry about the lifetime of the memory you've memory mapped (or copy your value type to the stack, as I do below) and your code now depends on the byte order of your machine. And this type of code is usually a bit more work to review for security & threading problems.

    That being said, we have code that does similar things inside the BCL, for loading resources and some globalization data tables. This example would be more interesting with a memory mapped file, but here's how you could quickly "copy" data to your data type. (Note that you could also avoid a memcpy by simply dereferencing the structure directly, but you also have to worry about the lifetime of your memory mapped file, or in this case, the pinning handle for the byte[]).

    <code>
    // Note the size of this value type is 16 bytes, so we can align field3
    // properly for a long.
    [StructLayout(LayoutKind.Sequential)]
    internal struct MyValueType
    {
    internal int field1;
    internal char field2;
    internal long field3; // Note alignment issues can cause problems.
    }

    private unsafe static void Main()
    {
    // This is dependent on your machine's byte order.
    byte[] array = new byte[16]; // zero'ed for us
    array[0] = 1; // Write 1 into field1
    array[4] = (byte) 'a'; // Write 'a' into field2
    array[8] = 3; // Write 3 into field3

    MyValueType v;
    fixed(byte* pBytes = array)
    v = *((MyValueType*) pBytes);
    Console.WriteLine("Field 1: {0} Field 2: {1} Field 3: {2}", v.field1, v.field2, v.field3);
    }
    </code>
Page 1 of 1 (3 items)