Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MemoryMappedFiles.MemoryMappedFile.CreateFromFile won't extend a file under linux/mono

Tags:

mono

f#

Under windows, this F# code will extend a file from say 12 bytes out to 655346 bytes when the capacity argument (last argument) is set to a larger size than the underlying file. This seems to be the cleanest way to extend a memory mapped file. Under mono / linux it throws an ArgumentException: capacity unless the file is as long as the mapped capacity. Is there a clean way to get mono to extend the file or do I have to preextend the file before I can map?

let Main () =
    let path = "parts.pash"
    let l = 65536L
    let mm =    MemoryMappedFiles.MemoryMappedFile.CreateFromFile(path,FileMode.OpenOrCreate,"pashmap",l)

    ()

Main()

Error message

Unhandled Exception: System.ArgumentException: capacity at System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (System.String path, FileMode mode, System.String mapName, Int64 capacity, MemoryMappedFileAccess access) [0x00000] in :0 at System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (System.String path, FileMode mode, System.String mapName, Int64 capacity) [0x00000] in :0 at Program.Main () [0x00000] in :0 at .$Program.main@ () [0x00000] in :0

Version of mono:

[daz@clowder pash]$ mono --version
Mono JIT compiler version 2.10.1 (tarball Mon Apr  4 10:40:52 PDT 2011)
Copyright (C) 2002-2011 Novell, Inc and Contributors. www.mono-project.com
        TLS:           __thread
        SIGSEGV:       altstack
        Notifications: epoll
        Architecture:  x86
        Disabled:      none
        Misc:          softdebug
        LLVM:          supported, not enabled.
        GC:            Included Boehm (with typed GC and Parallel Mark)

EDIT: it appears that the different underlying behaviour of memory mapping is exposed in the API so you need to extend the file yourself to the right length to be platform neutral

let f = File.Open(path,FileMode.Append,FileAccess.Write)
let pad = l- FileInfo(path).Length
let padding = Array.create (int32 pad) 0uy
f.Write(padding,0,int pad)
f.Close()
like image 967
Darren Avatar asked Mar 27 '12 18:03

Darren


1 Answers

Looking at the .NET implementation of CreateFromFile there is no implementation of that functionality. Other than argument checking, it is a slim wrapper around the Windows API call from what I can tell.

For this reason the ability to create a larger file is more of a happy coincidence from the .NET land, so it is no surprise that Mono removed that ability if the underlying operating system does not allow similar functionality.

Put more simply, not likely, since the .NET version doesn't technically extend the file either, the Windows API does.

like image 112
Guvante Avatar answered Nov 15 '22 09:11

Guvante