我正在尝试将文件从本地磁盘映射到内存中,以便我的程序可以访问文件内容。当对文件(大小不到 100kB)调用 mmap 时,我在调试器中查看从 mmap 返回的地址开始的内存,内存内容与文件内容不匹配(均以十六进制查看)。这不是字节交换问题。只有内存中的前 2 个字节与实际文件匹配,其余内容不匹配。
当我在一个包含字符串(例如:“hello world”)的小文件上重复相同的操作时,调试器中显示的内存与文件内容完全匹配(再次以十六进制显示)。
我尝试使用 MAP_PRIVATE 而不是 MAP_SHARED,但结果相同。我怎样才能让它与我更大的文件一起使用?
我在 Ubuntu 17.10 中使用 Eclipse 4.7.2 + CDT 并使用 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 构建配置调试 **** 让所有 构建文件:../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 构建完成(耗时 4 秒 438 毫秒)
最佳答案
mmap()
实际上并没有将整个文件读入内存,也没有实际分配文件大小的 RAM 量。它只是分配足够大的虚拟地址空间以“容纳”其中的文件。
它通过使用页面错误来工作,当您尝试读取文件的某些区域时,将分配实际的 RAM(或重用一些其他页面)并将一定数量的页面的数据从文件读入内存。
您几乎永远不会用mmap()
将整个文件加载到ram 中。但是您的程序应该可以工作,无论何时您尝试读取或写入数据(从程序,不是从调试器)一切都会正常工作。
是的,最重要的是,mmap()
的工作方式与 CreateFileMapping()
相同,因此您应该可以移植代码。
关于c++ - mmap 只适用于小文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49563607/