MemoryMappedFiles.MemoryMappedFile.CreateFromFile не будет расширять файл под linux / mono - PullRequest
6 голосов
/ 27 марта 2012

В Windows этот код F # будет расширять файл, скажем, с 12 байтов до 655346 байтов, если для аргумента емкости (последнего аргумента) задан больший размер, чем для базового файла. Похоже, что это самый чистый способ расширения файла отображения памяти. В режиме mono / linux он генерирует ArgumentException: емкость, если только файл не соответствует отображаемой емкости. Есть ли чистый способ получить моно для расширения файла, или мне нужно предварительно расширить файл, прежде чем я могу сопоставить?

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

    ()

Main()

Сообщение об ошибке

Необработанное исключение: System.ArgumentException: емкость при System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (Путь System.String, режим FileMode, имя System.String mapName, Int64 емкость, доступ к MemoryMappedFileAccess) [0x00000] в: 0 при System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (Путь System.String, режим FileMode, имя System.String mapName, Int64 емкость) [0x00000] в: 0 в Program.Main () [0x00000] в: 0 в . $ Program.main @ () [0x00000] в: 0

Версия моно:

[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)

РЕДАКТИРОВАТЬ: похоже, что в API представлено другое поведение отображения памяти, поэтому вам нужно самостоятельно расширить файл до нужной длины, чтобы быть нейтральной к платформе

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()

Ответы [ 2 ]

4 голосов
/ 28 марта 2012

Глядя на реализацию .NET CreateFromFile, эта функциональность не реализована. Помимо проверки аргументов, из того, что я могу сказать, это тонкая оболочка для вызова Windows API.

По этой причине возможность создания файла большего размера является более счастливым совпадением с земли .NET, поэтому неудивительно, что Mono удалил эту возможность, если базовая операционная система не поддерживает аналогичные функции.

Проще говоря, маловероятно, поскольку версия .NET также технически не расширяет файл, а Windows API делает это.

0 голосов
/ 03 сентября 2012

Вместо того, чтобы выделять потенциально большой массив и затем записывать его, поиск, вероятно, более эффективен. Я не уверен в коде F #, но в C # вы бы сделали что-то вроде:

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

С Mono 2.10.8 на Mac OS X поиск сам по себе был недостаточен, мне пришлось написать хотя бы один байт, несмотря на то, что в документации MSDN для FileStream.Seek сказано, что он расширит файл.

Кажется, что Mono может сделать нечто подобное в своей реализации MemoryMappedFile, чтобы сделать его более совместимым с .Net в Windows.

...