Home > front end >  Read C#'s MemoryMappedFile in Java
Read C#'s MemoryMappedFile in Java

Time:12-16

Hi and happy new year!

I've been looking for a way of doing this piece of code in Java/Kotlin, if possible...

MemoryMappedFile memfile = MemoryMappedFile.OpenExisting("MAHMSharedMemory");
BinaryReader br = new BinaryReader(memfile.CreateViewStream());
br.BaseStream.Seek(0, SeekOrigin.Begin);

The docs of OpenExisting states that:

Opens an existing memory-mapped file that has the specified name in system memory.

And the docs of CreateViewStream tells me:

Creates a stream that maps to a view of the memory-mapped file.

What would be the Java/Kotlin equivalent of those two methods?

CodePudding user response:

So as mentioned by @Etienne de Martel, we're not able to read it straight from Java without any help of JNA or JNI... Luckily there's another thread here on SO that pointed my in the right direction...

What I needed to do was:

public interface Kernel32Impl extends com.sun.jna.platform.win32.Kernel32 {
    Kernel32Impl KERNEL_32 = Native.load("kernel32", Kernel32Impl.class, W32APIOptions.DEFAULT_OPTIONS);
    HANDLE OpenFileMapping(int lfProtect, boolean bInherit, String lpName);
    HANDLE OpenEvent(int i, boolean bManualReset, String lpName);
}

and finally in Kotlin

class WindowsService {

    var lastError: Int = 0
        private set

    fun openMemoryMapFile(filename: String): WinNT.HANDLE? {
        val memMapFile = Kernel32Impl.KERNEL_32.OpenFileMapping(WinNT.SECTION_MAP_READ, false, filename)
        lastError = Kernel32Impl.KERNEL_32.GetLastError()

        return memMapFile
    }

    fun closeHandle(handle: WinNT.HANDLE) {
        Kernel32Impl.KERNEL_32.CloseHandle(handle)
    }

    fun mapViewOfFile(handle: WinNT.HANDLE?): Pointer? {
        handle ?: return null

        return Kernel32.INSTANCE.MapViewOfFile(handle, WinNT.SECTION_MAP_READ, 0, 0, 0)
    }

    fun unmapViewOfFile(pointer: Pointer) {
        Kernel32Impl.KERNEL_32.UnmapViewOfFile(pointer)
        lastError = Kernel32Impl.INSTANCE.GetLastError()
    }
}

Then on the actual usage of that:

windowsService.openMemoryMapFile(MEMORY_MAP_FILE_NAME)?.let { handle ->
            windowsService.mapViewOfFile(handle)?.let { pointer ->
                val buffer = ByteBuffer.allocateDirect(BLOCK_SIZE)
                buffer.put(pointer.getByteArray(0, BLOCK_SIZE))
                buffer.order(ByteOrder.LITTLE_ENDIAN)
                buffer.rewind()
  • Related