[英]mmap only works on small files?
我正在嘗試將文件從本地磁盤映射到內存,以便我的程序可以訪問文件內容。 在文件上調用mmap(大小不到100kB)時,我從mmap返回的地址開始查看調試器中的內存,並且內存內容與文件內容不匹配(均以十六進制查看)。 這不是字節交換問題。 僅內存中的前2個字節與實際文件匹配,其余內容不匹配。
當我在一個包含字符串的小文件(例如:“ hello world”)上重復相同的操作時,則在調試器中查看的內存與該文件的內容完全相同(再次以十六進制查看)。
我嘗試使用MAP_PRIVATE而不是MAP_SHARED,但結果相同。 我該如何處理更大的文件?
我正在使用Eclipse 4.7.2 + CDT在Ubuntu 17.10中進行工作,並在GDB中進行調試。
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>
#include <sys/mman.h>
int main()
{
void* MapAddr = NULL;
char* pData = NULL;
struct stat FileProps;
int FileDes = 0;
const char* fileNameAndPath = "/home/Test/testfile.txt";
FileDes = open(fileNameAndPath, O_RDWR);
if (FileDes != -1)
{
if (fstat(FileDes, &FileProps) == 0)
{
MapAddr = mmap(NULL, FileProps.st_size, (PROT_READ | PROT_WRITE), MAP_SHARED, FileDes, 0);
if (MapAddr == (void*) -1)
{
std::cout << "init: mmap failed" << std::endl;
return 0;
}
}
}
pData = (char*) MapAddr;
std::cout << pData << std::endl;
return 0;
}
13:10:42 ****為項目mmapTest構建配置調試****使所有Build文件都生成:../src/mmapTest.cpp調用:GCC C ++編譯器g ++ -O0 -g3 -Wall -c -fmessage- length = 0 -MMD -MP -MF“ src / mmapTest.d” -MT“ src / mmapTest.o” -o“ src / mmapTest.o”“ ../src/mmapTest.cpp”完成的建築:../ SRC / mmapTest.cpp
構建目標:mmapTest調用:GCC C ++鏈接器g ++ -o“ mmapTest” ./src/mmapTest.o
完成的建築目標:mmapTest
13:10:46構建完成(耗時4s.438ms)
mmap()
實際上不會將整個文件讀入內存,也不會實際分配文件大小的RAM量。 它只是分配足夠大的虛擬地址空間以“適合”其中的文件。
它通過使用頁面錯誤來工作,當您嘗試讀取文件的某些區域時,將分配實際的RAM(或重用某些其他頁面),並將一定量的頁面數據從文件中讀取到內存中。
您幾乎不會使用mmap()
將整個文件加載到ram中。 但是您的程序應該可以工作,每當您嘗試(從程序而不是從調試器)讀取或寫入數據時,一切都將正常運行。
而且,是的,最重要的是, mmap()
工作方式與CreateFileMapping()
相同,因此您應該可以移植代碼。
我確定運行mmap()后內存內容(在GDB調試器中查看)與實際文件內容不匹配的原因是,我映射的文件未經過ANSI編碼。 因此,調試器將顯示Linux認為應該的正確數據。 在以ANSI格式保存文件(在文本鍵盤中)后,在Linux中查看的文件二進制內容與在Windows中查看的二進制內容相同。 無需更改代碼。 問題在於正在映射的文件。 與其中一項評論相反,GDB調試器可以在mmap()返回的地址處使用內存查看器顯示所有映射的文件數據-我已經確認了最大100KB的文件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.