2012-04-15 33 views
0

雖然處理一個非常大的二進制文件可以使用C中的內存映射與fread相比有什麼不同?即使時間稍有不同,也可以。如果它確實讓流程更容易理解如何在大型二進制文件上使用內存映射並從中提取數據?在C中使用內存映射來讀取二進制文件

謝謝!

+0

這是所有平臺特定的。 C語言本身不提供任何方式來存儲映射文件。如果不指定平臺,您將無法得到明智的答案。沒有關於訪問模式的詳細信息,您將無法得到「爲什麼」部分的明智答案。 – 2012-04-15 04:34:10

+0

它是在Linux平臺上 – AndroidDev93 2012-04-15 04:37:28

+0

然後短的「如何」的答案是「man mmap」。但對於「爲什麼」,我們仍然需要知道訪問模式。 (隨機?順序?每個字節只有一次?一些字節比其他更多?小讀取?大讀?這是剛剛讀?) – 2012-04-15 04:39:48

回答

1

如果您要從頭到尾閱讀整個文件,最重要的是讓平臺知道這一點。這將允許它進行積極的預讀,並且它將允許它避免使用不會被再次讀取的數據來污染緩存。您可以使用內存映射或不使用內存映射。關鍵功能是posix_fadviseposix_madvise

當你有隨機的小訪問時,內存映射是一個巨大的勝利。當您對同一頁面進行多次寫入時尤其如此。沒有內存映射,每個讀或寫操作都需要用戶/內核轉換和副本。使用內存映射,大多數操作不會。

但順序訪問,所有將保存是副本。奇怪的是,用戶/內核轉換可能更糟糕。對於大量順序讀取,每次讀取都會得到一次用戶/內核轉換,如果讀取量較大,則每個讀取可能爲每個256KB。通過對內存映射文件的大量順序訪問,每個頁面可能會出錯(4KB)。這取決於內核的「提前出錯」優化。

但是,使用內存映射,您將保存副本,假設您不需要執行副本。如果您出於任何原因必須從映射頁面中複製出來,那麼您可以讓read操作將它們複製到您的位置。但是,如果您可以對數據進行操作,則內​​存映射可能是一個勝利。

它通常不會像人們傾向於認爲的那麼大。特別是當你考慮磁盤與所有這些東西相比有多慢時。

+0

謝謝你。所以當我嘗試做內存映射時,我收到了一些編譯錯誤。我的代碼是這樣的: 的#include 的#include 的#include INT FD; char * data; fd = open(「data.bin」,O_RDONLY); data = mmap((caddr_t)0,4000,PROT_READ,MAP_SHARED,fd, 4000); 基本上我得到一個錯誤,說caddr_t初始化和O_RDONLY相同。它還表示mmap的參數太少 – AndroidDev93 2012-04-15 05:14:04

+1

「mmap」的第一個參數應該只是「NULL」。此外,4,000不是合法抵消。 (偏移量必須是頁面大小的倍數。) – 2012-04-15 05:29:54