Skip to content

Instantly share code, notes, and snippets.

@airbreather
Created January 29, 2017 12:54
Show Gist options
  • Save airbreather/bdd3ce6d13d7a15e1986d2ed9c3f5e7d to your computer and use it in GitHub Desktop.
Save airbreather/bdd3ce6d13d7a15e1986d2ed9c3f5e7d to your computer and use it in GitHub Desktop.
Basic adapter for System.IO.MemoryMappedFiles
using System;
using System.Buffers;
using System.IO;
using System.IO.MemoryMappedFiles;
namespace AirBreather.IO
{
public static class MemoryMappedFileEx
{
public static unsafe OwnedMemory<byte> CreateFromFile(string filePath, FileMode mode, string mapName, long offset, long totalCapacity, MemoryMappedFileAccess access)
{
byte* ptr = null;
MemoryMappedFile fl = null;
MemoryMappedViewAccessor acc = null;
try
{
fl = MemoryMappedFile.CreateFromFile(filePath, mode, mapName, totalCapacity, access);
acc = fl.CreateViewAccessor(offset, totalCapacity - offset, access);
acc.SafeMemoryMappedViewHandle.AcquirePointer(ref ptr);
ptr += acc.PointerOffset;
return new OwnedMappedMemory(fl, acc, ref ptr);
}
catch
{
acc?.Dispose();
fl?.Dispose();
throw;
}
finally
{
if (ptr != null)
{
acc.SafeMemoryMappedViewHandle.ReleasePointer();
}
}
}
private sealed class OwnedMappedMemory : OwnedMemory<byte>
{
private MemoryMappedFile fl;
private MemoryMappedViewAccessor acc;
internal unsafe OwnedMappedMemory(MemoryMappedFile fl, MemoryMappedViewAccessor acc, ref byte* acquiredPointer)
: base(null, 0, checked((int)acc.Capacity), new IntPtr(acquiredPointer))
{
this.fl = fl;
this.acc = acc;
// signal that we are now responsible for releasing the pointer.
acquiredPointer = null;
}
~OwnedMappedMemory()
{
this.Dispose(false);
}
protected override void Dispose(bool disposing)
{
this.acc.SafeMemoryMappedViewHandle.ReleasePointer();
if (disposing)
{
this.acc.Dispose();
this.fl.Dispose();
GC.SuppressFinalize(this);
}
base.Dispose(disposing);
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment