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

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.h | windows.h |
| 文件大小设置 | 使用ftruncate函数 | 使用SetFilePointer配合SetEndOfFile |
| 数据同步 | 使用msync函数 | 映射取消时自动同步,也可调用FlushViewOfFile |
| 资源释放 | munmap释放映射,close关闭文件描述符 | UnmapViewOfFile取消映射,CloseHandle关闭句柄 |
使用内存映射文件时需要注意,映射大小不能超过文件实际大小,修改映射区域的数据时要避免越界访问,跨平台开发时可以根据操作系统宏区分调用不同的实现接口。
C++mmapCreateFileMapping内存映射文件文件读写修改时间:2026-07-07 11:12:37