c++ - mmap 只适用于小文件?

标签 c++ linux memory mmap

我正在尝试将文件从本地磁盘映射到内存中,以便我的程序可以访问文件内容。当对文件(大小不到 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/

相关文章:

迭代器和循环引用的 C++ 容器

linux - 创建虚拟主机Centos

linux - 如何在嵌入式设备上实现网络服务?

c# - 访问 LTO 磁带内存的源代码 (C/C#)

c++ - 使用结构化异常处理 (SEH) 的后果?

c++ - make 如何推断最终目标需要什么样的编译器?

n 秒内的 Docker 统计信息

c++ - 静态分配的内存在静态取消初始化期间会变得无效吗?

c++ - lexical_cast strtof strtold 失去准确性?

linux - 测试 SLOB - 如何?