2012-03-27 13 views
6

Unter Windows wird dieser F # -Code eine Datei von etwa 12 Byte auf 655346 Byte erweitern, wenn das Argument Kapazität (letztes Argument) auf eine größere Größe gesetzt wird als die zugrunde liegende Datei. Dies scheint der sauberste Weg zu sein, eine Memory-Mapped-Datei zu erweitern. Unter mono/linux wird eine ArgumentException: capacity ausgelöst, es sei denn, die Datei ist so lang wie die zugeordnete Kapazität. Gibt es eine saubere Möglichkeit, um mono zu erweitern, oder muss ich die Datei vorziehen, bevor ich es zuordnen kann?MemoryMappedFiles.MemoryMappedFile.CreateFromFile erweitert keine Datei unter linux/mono

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

    () 

Main() 

Fehlermeldung

Unbehandelte Ausnahme: System.ArgumentException: Kapazität bei System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (System.String Pfad, Filemode-Modus System.String mapName, Int64 Kapazität, MemoryMappedFileAccess access) [0x00000] in: 0 bei System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (System.String Pfad, Filemode-Modus System.String mapName, Int64 Kapazität) [0x00000] in: 0 at Program.Main() [0x00000] in: 0 bei $ Program.main @() [0x00000] in:. 0

Version von Mono:

[[email protected] 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: es scheint, dass das verschiedene zugrunde liegende Verhalten von Speicherzuordnung wird in der API ausgesetzt, so dass Sie die Datei selbst auf die richtige Länge erweitern sein müssen Plattform 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() 

Antwort

4

mit Blick auf der .NET-Implementierung von CreateFromFile gibt es keine Implementierung dieser Funktionalität. Abgesehen von der Überprüfung von Argumenten ist es ein schlanker Wrapper um den Windows-API-Aufruf von dem, was ich sagen kann.

Aus diesem Grund ist die Möglichkeit, eine größere Datei zu erstellen, eher eine glückliche Fügung aus dem .NET Land, also ist es keine Überraschung, dass Mono diese Fähigkeit entfernt, wenn das zugrundeliegende Betriebssystem ähnliche Funktionalität nicht zulässt.

Einfacher ausgedrückt, nicht wahrscheinlich, da die .NET-Version die Datei technisch nicht erweitert, tut das Windows-API.

+0

Das scheint wie eine schlanke Verteidigung der API :) Die Dokumente für die Funktion listet die Umstände, unter denen eine ArgumentException ausgelöst werden kann, und sie erwähnen nicht die Kapazität Argument. Ich denke, man könnte argumentieren, dass der .NET-Vertrag "wie immer das zugrunde liegende Betriebssystem funktioniert" ist, aber das ist ein schlechter Weg, um eine API auszuführen. – Darren

+0

@Darren: Nicht als eine Verteidigung gemeint, nur als eine Feststellung der Tatsache gemeint. In der Regel sprudeln die Implementierungsdetails des Betriebssystems aus Gründen der Einfachheit heraus, dies ist für den Benutzer keineswegs ideal. – Guvante

+1

@Darren: Um die Sache noch schlimmer zu machen, ist die einzige zuverlässige Methode, die Methode aufzurufen, die genaue Dateigröße. Windows lässt weniger als die Dateigröße zu und Mono unter UNIX lässt mehr als die Dateigröße zu. – Guvante

0

Anstatt ein potenziell großes Array zuzuordnen und dann zu schreiben, ist es wahrscheinlich effizienter zu suchen. Ich bin mir nicht sicher, ob der F # -Code, aber in C# würden Sie tun so etwas wie:

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

Mit Mono 2.10.8 auf Mac OS X selbst sucht nicht ausreichend war, hatte ich wenigstens einen schreiben Byte, trotz der MSDN-Dokumentation für FileStream.Seek sagen, dass es die Datei erweitern wird.

Es scheint, als könnte Mono etwas Ähnliches in seiner MemoryMappedFile-Implementierung tun, um es kompatibler zu .Net unter Windows zu machen.