2012-03-27 19 views
6

Dưới cửa sổ, mã F # này sẽ mở rộng tệp từ 12 byte ra ngoài thành 655346 byte khi đối số công suất (đối số cuối cùng) được đặt thành kích thước lớn hơn so với tệp cơ bản. Điều này có vẻ là cách sạch nhất để mở rộng một tệp ánh xạ bộ nhớ. Dưới mono/linux nó ném một khả năng ArgumentException: trừ khi tệp đó miễn là dung lượng được ánh xạ. Có cách nào sạch sẽ để có được mono để mở rộng các tập tin hoặc làm tôi phải preextend tập tin trước khi tôi có thể bản đồ?MemoryMappedFiles.MemoryMappedFile.CreateFromFile sẽ không mở rộng tệp dưới linux/mono

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

    () 

Main() 

Thông báo lỗi

Unhandled Exception: System.ArgumentException: Công suất tại System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (đường dẫn System.String, chế độ chế độ File, System.String mapName, Int64 dung lượng, truy cập MemoryMappedFileAccess) [0x00000] tại: 0 tại System.IO.MemoryMappedFiles.MemoryMappedFile.CreateFromFile (Đường dẫn hệ thống.String, chế độ FileMode, System.String mapName, Int64 capacity) [0x00000] in: 0 at Program.Main() [0x00000] tại: 0 tại $ Program.main @() [0x00000] tại:. 0

Phiên bản 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: nó xuất hiện mà hành vi tiềm ẩn khác nhau của bản đồ bộ nhớ được tiếp xúc trong API, do đó bạn cần phải mở rộng tập tin bản thân để chiều dài đúng là nền tảng trung lập

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

Trả lời

4

Nhìn vào thực hiện NET của CreateFromFile không có thực hiện chức năng đó. Khác với kiểm tra đối số, nó là một wrapper mỏng xung quanh cuộc gọi Windows API từ những gì tôi có thể nói. Vì vậy, không có gì ngạc nhiên khi Mono loại bỏ khả năng đó nếu hệ điều hành bên dưới không cho phép chức năng tương tự.

Đặt đơn giản hơn, không có khả năng, vì phiên bản .NET không mở rộng tệp kỹ thuật, API Windows sẽ thực hiện.

+0

Điều đó có vẻ giống như một bảo vệ mỏng của API :) Các tài liệu cho hàm liệt kê các trường hợp mà theo đó một ArgumentException có thể được nâng lên và chúng không đề cập đến đối số công suất. Tôi đoán bạn có thể lập luận rằng hợp đồng .NET là "bất kỳ hệ điều hành cơ bản nào cảm thấy thích làm" nhưng đó là một cách kém để chạy một API. – Darren

+0

@ Darren: Không có nghĩa là phòng thủ, có nghĩa là một tuyên bố thực tế. Thông thường các chi tiết thực hiện của bong bóng hệ điều hành không cần thiết cho sự đơn giản, điều này không có nghĩa lý tưởng cho người dùng. – Guvante

+1

@ Darren: Để làm cho vấn đề tồi tệ hơn, cách đáng tin cậy duy nhất để gọi phương thức là với kích thước tệp chính xác. Windows không cho phép kích thước tệp nhỏ hơn và Mono trên UNIX không cho phép lớn hơn kích thước tệp. – Guvante

0

Thay vì phân bổ một mảng có khả năng lớn, và sau đó viết nó, nó có thể hiệu quả hơn để tìm kiếm. Tôi không chắc chắn của # mã F, nhưng trong C# bạn muốn làm điều gì đó như:

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

Với Mono 2.10.8 trên Mac OS X tìm kiếm bởi chính nó là không đủ, tôi đã phải viết ít nhất một byte, mặc dù tài liệu MSDN cho FileStream.Seek nói rằng nó sẽ mở rộng các tập tin.

Dường như Mono có thể làm điều gì đó tương tự trong triển khai MemoryMappedFile của họ để làm cho nó tương thích hơn với .Net trên Windows.

Các vấn đề liên quan