简体   繁体   中英

Clearing contents of memory mapped file in C#

I am using MemoryMappedFile for communication between 2 programs. Program "A" creates the mmf and reads it's contents on a timer. Program "B" writes xml data to the mmf on a timer. I have the memory map working but I run into an issue where the previous iteration of the XML data is longer than the current and old data gets carried over to the next round.

so for simplicity lets say program B writes

aaaa

Program A will read correctly,

Then the next write from program B is:

b

Program A reads

baaa

It seems like there should be some simple way to flush the contents of the memory mapped file but I can't seem to figure it out. It's very possible that I'm totally wrong in the way I'm going about this.

Here's what I'm currently doing.

Program A:

using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap",MemoryMappedFileRights.ReadWrite))
{

    Mutex mutex = Mutex.OpenExisting("testmapmutex");
    mutex.WaitOne();
    string outputtext;
    using (MemoryMappedViewStream stream = mmf.CreateViewStream(0,0))
    {

        XmlSerializer deserializer = new XmlSerializer(typeof(MyObject));
        TextReader textReader = new StreamReader(stream);
        outputtext = textReader.ReadToEnd();
        textReader.Close();

    }

    mutex.ReleaseMutex();
    return outputtext; //ends up in a textbox for debugging

}

Program B

using (MemoryMappedFile mmf = MemoryMappedFile.OpenExisting("testmap", MemoryMappedFileRights.ReadWrite))
{

    Mutex mutex = Mutex.OpenExisting("testmapmutex");
    mutex.WaitOne();

    using (MemoryMappedViewStream stream = mmf.CreateViewStream(0, 0))
    {


        XmlSerializer serializer = new XmlSerializer(typeof(MyObject));
        TextWriter textWriter = new StreamWriter(stream);
        serializer.Serialize(textWriter, myObjectToExport);
        textWriter.Flush();

    }
    mutex.ReleaseMutex();

}

Assuming length is reasonably small, you could really clear it out

textWriter.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
textWriter.BaseStream.Write(new byte[length], 0, length);
textWriter.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);

EDIT: I think I misunderstood the OP's question. The problem he was having was not with clearing the contents of the MMF, but with stream manipulation. This should fix the problem:

textWriter.BaseStream.Seek(0, System.IO.SeekOrigin.Begin);
textWriter.Write("");
textWriter.Flush();

That being said, you might want to do both.

I haven't really worked with MemoryMappedStreams much but this question seemed interesting so I took a crack at it. I wrote a really basic windows example with two buttons (read/write) and a single text box. I didn't pass in "0, 0" to the CreateViewStream calls and I created the file with a fixed length using a call to "CreateOrOpen" and everything worked well! The following are the key pieces of code that I wrote:

WRITE The File

// create the file if it doesn't exist
if (sharedFile == null) sharedFile = MemoryMappedFile.CreateOrOpen("testmap", 1000, MemoryMappedFileAccess.ReadWrite);

// process safe handling
Mutex mutex = new Mutex(false, "testmapmutex");

if (mutex.WaitOne()) {
    try {
        using (MemoryMappedViewStream stream = sharedFile.CreateViewStream()) {
            var writer = new StreamWriter(stream);
            writer.WriteLine(txtResult.Text);
            writer.Flush();
        }
    }
    finally { mutex.ReleaseMutex(); }
}

READ The File

// create the file if it doesn't exist
if (sharedFile == null) sharedFile = MemoryMappedFile.CreateOrOpen("testmap", 1000, MemoryMappedFileAccess.ReadWrite);

// process safe handling
Mutex mutex = new Mutex(false, "testmapmutex");

if (mutex.WaitOne()) {
    try {
        using (MemoryMappedViewStream stream = sharedFile.CreateViewStream()) {
            var textReader = new StreamReader(stream);
            txtResult.Text = textReader.ReadToEnd();
            textReader.Close();
        }
    }
    finally { mutex.ReleaseMutex(); }
}

Dispose the file (after finished)

if (sharedFile != null) sharedFile.Dispose();

For the full example, see here: https://github.com/goopyjava/memory-map-test . Hope that helps!

EDIT/NOTE - If you look at the example provided you can write to the file as many times as you want and any time you read you will read exactly/only what was written last. I believe this was the original goal of the question.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM