MMAP仅适用于小文件



我正在尝试将文件从本地磁盘映射到内存中,以便我的程序可以访问文件内容。当在文件上调用MMAP(大小不足100KB(时,我会在MMAP返回的地址开始调试器中的内存,并且内存内容与文件内容不匹配(均在十六进制中查看(。这是不是字节交换问题。只有内存中的前两个字节和实际文件匹配,其余内容则不。

当我在包含字符串的小文件上重复相同的内容(ex:" 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 -MP -MP -MMF'SRC/MMAPTEST.D" -MT" SRC/MMAPTEST.O" -O" -O" -O" SRC/MMATTEST.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()相同,因此您应该可以移植代码。

i确定了内存内容(如GDB调试器中所示(的原因,在运行mmap((之后,我映射的文件是不是ANSI编码。因此,调试器显示了正确的数据,正如Linux认为应该的那样。在使用ANSI格式保存文件(在TextPad中(后,Linux中查看的文件的二进制内容与Windows中查看的二进制内容相同。无需更改代码。问题在于文件被映射。与其中一条注释相反,GDB调试器能够通过MMAP((返回的地址显示所有映射的文件数据 - 我已经确认了该文件,最高为100KB。

最新更新