繁体   English   中英

mmap仅适用于小文件?

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM