MemoryMappedFiles.MemoryMappedFile.CreateFromFile will not expand the file under linux / mono

In windows, this F # code will expand the file from 12 bytes to 655346 bytes if the capacity argument (last argument) is set to a larger size than the base file. This is apparently the cleanest way to expand a memory-mapped file. In mono / linux, it throws an ArgumentException: capacity property if the file does not have the same length as the displayed capacity. Is there a clean way to get mono to expand the file, or do I need to unzip the file before I can display it?

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 (Path System.String, FileMode mode, System_name System.StringName, Int64 capacity, memory access MemoryMappedFileAccess) [0x00000] at: 0 on System.IO .MemoryMappedFiles.MemoryMappedFile.CreateFromFile (Path System.String, FileMode mode, SystemName System.StringName, Int64 capacity) [0x00000] at: 0 on Program.Main () [0x00000] at: 0 on. $ Program.main @ () [0x00000] at: 0

Mono version:

 [ 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 looks like the base interface displays different basic memory mapping behavior, so you need to expand the file yourself to the desired length to be a neutral platform.

 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() 
+6
source share
2 answers

Looking at the .NET implementation in CreateFromFile , there is no implementation for this function. Due to what I can say, besides checking the arguments, this is a thin shell around calling the Windows API.

For this reason, the ability to create a larger file is happier coinciding with .NET ground, so it is not surprising that Mono removed this feature if the underlying operating system does not allow the use of similar functions.

Simply put, this is unlikely, since the .NET version does not technically extend the Windows API file.

+4
source

Instead of allocating a potentially large array and then writing it, it is probably more efficient for searching. I'm not sure about the F # code, but in C # you would do something like:

  filestream.Seek(length - 1, SeekOrigin.Begin); filestream.WriteByte(0); 

With Mono 2.10.8 on Mac OS X the search was not enough, I had to write at least one byte, despite the MSDN documentation for FileStream.Seek saying that it would expand the file.

It seems Mono can do something similar in its MemoryMappedFile implementation to make it more compatible with .Net on Windows.

0
source

Source: https://habr.com/ru/post/911785/


All Articles