导读:本期聚焦于小伙伴创作的《C++如何实现内存映射文件的高效读写?mmap与CreateFileMapping源码解析》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《C++如何实现内存映射文件的高效读写?mmap与CreateFileMapping源码解析》有用,将其分享出去将是对创作者最好的鼓励。

内存映射文件通过将磁盘文件的内容直接映射到进程的虚拟地址空间,让程序可以像访问内存一样操作文件数据,大幅减少传统读写方式中数据拷贝的开销,尤其适合大文件的随机读写场景。C++在不同操作系统下提供了不同的内存映射文件实现接口,Linux平台常用mmap函数,Windows平台则使用CreateFileMapping配合MapViewOfFile实现。

C++如何实现内存映射文件的高效读写?mmap与CreateFileMapping源码解析

Linux平台mmap实现内存映射文件读写

Linux系统下使用mmap函数完成内存映射,需要先打开目标文件获取文件描述符,再调用mmap建立映射关系,操作完成后需要同步数据并释放映射。

mmap函数核心参数说明

  • addr:映射区的起始地址,通常设为NULL让系统自动分配
  • length:映射区的大小,单位字节
  • prot:映射区的保护权限,PROT_READ表示可读,PROT_WRITE表示可写
  • flags:映射标志,MAP_SHARED表示修改会同步到文件,MAP_PRIVATE表示修改仅私有
  • fd:文件描述符,由open函数返回
  • offset:文件映射的起始偏移量,需要是页大小的整数倍

完整读写示例代码

#include <iostream>
#include <fcntl.h>
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
#include <cstring>

int main() {
    // 打开文件,不存在则创建,权限为读写
    int fd = open("test_linux.txt", O_RDWR | O_CREAT, 0666);
    if (fd == -1) {
        std::cerr << "打开文件失败" << std::endl;
        return 1;
    }

    // 设置文件大小为1024字节
    ftruncate(fd, 1024);

    // 建立内存映射,可读可写,修改同步到文件
    void* map_addr = mmap(NULL, 1024, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if (map_addr == MAP_FAILED) {
        std::cerr << "内存映射失败" << std::endl;
        close(fd);
        return 1;
    }

    // 写入数据到映射区域
    const char* write_data = "这是通过mmap写入的测试数据";
    memcpy(map_addr, write_data, strlen(write_data) + 1);

    // 同步映射数据到文件
    msync(map_addr, 1024, MS_SYNC);

    // 读取映射区域的数据
    std::cout << "读取到的数据:" << (char*)map_addr << std::endl;

    // 释放映射
    munmap(map_addr, 1024);
    // 关闭文件描述符
    close(fd);
    return 0;
}

Windows平台CreateFileMapping实现内存映射文件读写

Windows平台下需要先通过CreateFile打开文件,再调用CreateFileMapping创建文件映射对象,最后使用MapViewOfFile将映射对象映射到进程地址空间。

核心函数说明

  • CreateFile:打开或创建文件,返回文件句柄
  • CreateFileMapping:创建文件映射对象,指定映射大小和访问权限
  • MapViewOfFile:将文件映射对象映射到进程虚拟地址空间,返回映射地址
  • UnmapViewOfFile:取消地址空间的映射
  • CloseHandle:关闭文件句柄和映射对象句柄

完整读写示例代码

#include <iostream>
#include <windows.h>
#include <cstring>

int main() {
    // 打开文件,不存在则创建,可读可写
    HANDLE hFile = CreateFile(
        "test_windows.txt",
        GENERIC_READ | GENERIC_WRITE,
        0,
        NULL,
        OPEN_ALWAYS,
        FILE_ATTRIBUTE_NORMAL,
        NULL
    );
    if (hFile == INVALID_HANDLE_VALUE) {
        std::cerr << "打开文件失败" << std::endl;
        return 1;
    }

    // 设置文件大小为1024字节
    SetFilePointer(hFile, 1024, NULL, FILE_BEGIN);
    SetEndOfFile(hFile);

    // 创建文件映射对象,可读可写
    HANDLE hMap = CreateFileMapping(
        hFile,
        NULL,
        PAGE_READWRITE,
        0,
        1024,
        NULL
    );
    if (hMap == NULL) {
        std::cerr << "创建文件映射对象失败" << std::endl;
        CloseHandle(hFile);
        return 1;
    }

    // 映射文件到进程地址空间
    void* map_addr = MapViewOfFile(
        hMap,
        FILE_MAP_ALL_ACCESS,
        0,
        0,
        1024
    );
    if (map_addr == NULL) {
        std::cerr << "映射文件到地址空间失败" << std::endl;
        CloseHandle(hMap);
        CloseHandle(hFile);
        return 1;
    }

    // 写入数据到映射区域
    const char* write_data = "这是通过CreateFileMapping写入的测试数据";
    memcpy(map_addr, write_data, strlen(write_data) + 1);

    // 读取映射区域的数据
    std::cout << "读取到的数据:" << (char*)map_addr << std::endl;

    // 取消映射
    UnmapViewOfFile(map_addr);
    // 关闭句柄
    CloseHandle(hMap);
    CloseHandle(hFile);
    return 0;
}

两种实现的对比与注意事项

对比项mmap(Linux)CreateFileMapping(Windows)
依赖头文件fcntl.h、sys/mman.h、sys/stat.h、unistd.hwindows.h
文件大小设置使用ftruncate函数使用SetFilePointer配合SetEndOfFile
数据同步使用msync函数映射取消时自动同步,也可调用FlushViewOfFile
资源释放munmap释放映射,close关闭文件描述符UnmapViewOfFile取消映射,CloseHandle关闭句柄

使用内存映射文件时需要注意,映射大小不能超过文件实际大小,修改映射区域的数据时要避免越界访问,跨平台开发时可以根据操作系统宏区分调用不同的实现接口。

C++mmapCreateFileMapping内存映射文件文件读写修改时间:2026-07-07 11:12:37

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。