2017-04-04 275 views
-1

編輯:如果你想downvote,請解釋爲什麼請。不幫助任何人。如何正確使用MemoryMappedViewAccessor?

我真的很想了解如何正確使用內存映射文件,但我遇到了一些問題。這裏的場景:

我有一些大文件,從1-10 GB的任何地方。這些文件由structs組成,除文件的第一個外,全部128字節。

我需要對這些結構中的任何一個進行快速的隨機訪問,從我讀的是內存映射文件是完美的。我也需要這些內存映射文件能夠被其他進程打開,但不會有任何寫入,只是讀取文件。

我能夠確定我需要閱讀的確切結構的字節偏移量。

首先我試圖使該MEM映射文件像這樣:

MemoryMappedFile hFileMapping = MemoryMappedFile.CreateFromFile(rampPath, FMode, Path.GetFileNameWithoutExtension(rampPath), GetFileLength(rampPath), access); 

但是,其他進程無法打開它。所以我發現有另外一個構造函數需要輸入FileStream。所以我將它改爲:

FileStream fs = new FileStream(rampPath, FileMode.OpenOrCreate, FileAccess.Read, FileShare.Read); 
MemoryMappedFile hFileMapping = MemoryMappedFile.CreateFromFile(fs, Path.GetFileNameWithoutExtension(rampPath), GetFileLength(rampPath), access, null, HandleInheritability.Inheritable, true); 

其他進程現在可以打開mem映射文件。然後我嘗試使映射文件的視圖:

MemoryMappedViewAccessor hFileAccessor = hFileMapping.CreateViewAccessor(0, GetFileLength(rampPath), MemoryMappedFileAccess.Read)); 

這是好的,如果文件很小,但如果是大我得到out of storage和內存異常。

所以我需要一次只映射文件的一部分,但什麼是確定我正在尋找的結構是否在當前映射視圖中的最佳方法是什麼?我是否跟蹤當前映射視圖的偏移量和長度,並查看結構的偏移量是否在那裏?有沒有更好的方法去解決這一切?

+1

如果您的主標識符是連續的,那麼您可以使用基於已知大小和偏移量的計算。如果頁面在內存中那麼很好,如果不是,那麼你有一個明確的偏移量,你需要閱讀來到你認爲你感興趣的記錄可能在哪裏。如果你不能使用順序訪問方法,那麼你將不得不從頭到尾閱讀你的分區,然而,你可以建立技術來提高效率,比如在讀取結構和其他索引時緩存標識符和分區偏移量 - ' 'esque'東西。 –

+1

使用ViewAccessor的記錄讀取記錄可能適用於您,但是,根據工作負載的不同,較大的跳數可能會更有效。 –

+0

謝謝! 「主標識符是順序的」是什麼意思? – pfinferno

回答

0

感謝@羅斯布什在OP的建議的意見。

我所做的只是讓ViewAccessor的容量始終保持一定數量。因爲我有我需要的字節偏移量,所以我只是運行一些計算來確定字節偏移量是否在ViewAccessor之內。如果不是,則將ViewAccessor更改爲不同的偏移量/容量,以便字節偏移量落入其中。