app开发和网站开发哪个好,益阳做网站,服务器网站 都被做跳转,汉沽手机网站建设概念
将一个文件直接映射到进程的进程空间中#xff08;“映射”就是建立一种对应关系,这里指硬盘上文件的位置与进程逻辑地址空间中一块相同区域之间一 一对应,这种关系纯属是逻辑上的概念#xff0c;物理上是不存在的#xff09;#xff0c;这样可以通过内存指针用读写内…概念
将一个文件直接映射到进程的进程空间中“映射”就是建立一种对应关系,这里指硬盘上文件的位置与进程逻辑地址空间中一块相同区域之间一 一对应,这种关系纯属是逻辑上的概念物理上是不存在的这样可以通过内存指针用读写内存的办法直接存取文件内容。特点
文件数据可以用内存读/写指令来访问而不是用Read和Write这样的I/O系统函数从而提高了文件存取速度。流程
打开文件创建文件句柄为文件创建内存映射内核对象返回内存映射文件句柄映射整个文件或一部分到进程的虚拟地址空间返回文件映射到内存后的起始地址解除文件映射关闭内存映射文件句柄关闭文件句柄
函数
1创建文件句柄。
windows
# 函数
HANDLE CreateFile(LPCTSTR lpFileName, //普通文件名或者设备文件名DWORD dwDesiredAccess, //访问模式写/读DWORD dwShareMode, //共享模式LPSECURITY_ATTRIBUTES lpSecurityAttributes, //指向安全属性的指针DWORD dwCreationDisposition, //如何创建DWORD dwFlagsAndAttributes, //文件属性HANDLE hTemplateFile //用于复制文件句柄
);linux
# 函数
int open(const char *pathname, int flags, mode_t mode);2创建内存映射内核对象。
windows
# 函数
HANDLE CreateFileMapping(HANDLE hFile, // 文件句柄填写 INVALID_HANDLE_VALUELPSECURITY_ATTRIBUTES lpFileMappingAttributes, // 安全描述符填写 NULL DWORD flProtect, // 映射对象保护属性DWORD dwMaximumSizeHigh, // 文件映射的最大长度的高32位DWORD dwMaximumSizeLow, // 文件映射的最大长度的低32位LPCTSTR lpName // 文件映射对象名称
);linux
# 函数
void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);# 参数说明
## start映射区的开始地址
## length映射区的长度
## prot期望的内存保护标志不能与文件的打开模式冲突。是以下的某个值可以通过or运算合理地组合在一起
## flags指定映射对象的类型映射选项和映射页是否可以共享。
## fd有效的文件描述词。如果MAP_ANONYMOUS被设定为了兼容问题其值应为-1
## offset被映射对象内容的起点。3映射文件到进程的虚拟地址空间。
windows
# 函数
LPVOID MapViewOfFile(HANDLE hFileMappingObject, // CreateFileMapping()返回的文件映像对象句柄DWORD dwDesiredAccess, // 数据的访问方式DWORD dwFileOffsetHigh, // 文件映射起始偏移的高32位DWORD dwFileOffsetLow, // 文件映射起始偏移的低32位DWORD dwNumberOfBytesToMap // 文件中要映射的字节数为0表示映射整个文件映射对象
);4在接收进程中打开对应的内存映射对象。
# 函数
HANDLE OpenFileMapping(DWORD dwDesiredAccess, // 数据的访问方式BOOL bInheritHandle, // 是否继承句柄LPCTSTR lpName // 要打开的文件映射对象名称
);5回写内存映射文件。
windows
# 函数
BOOL FlushViewOfFile(LPCVOID lpBaseAddress, // 开始的地址SIZE_T dwNumberOfBytesToFlush // 数据块的大小
);linux
#include sys/mman.h# 函数
int msync(void *addr, size_t length, int flags);# 参数说明
## 内存段需要修改的部分作为参数传递过来的起始地址addr和长度len确定。
## flags 参数控制着执行修改的具体方式
#### MS_ASYNC 采用异步写方式
#### MS_SYNC 采用同步写方式
#### MS_INVALIDATE 从文件中读回数据6解除文件映射。
windows
# 函数
BOOL UnmapViewOfFile(LPCVOID lpBaseAddress);# 参数说明
## lpBaseAddress: 指向要取消映射的文件的映射视图基址的指针。此值必须与上一次调用 MapViewOfFile或 MapViewOfFileEx 函数返回的值相同。linux
# 函数
int munmap(void * addr, size_t len);# 参数说明
## addr:映射内存起始地址
## len: 欲取消的内存大小# 返回值
执行成功时munmap()返回0。失败时munmap返回-1。示例
windows实例
#include iostream
#include stdio.h
#include windows.h
#include chrono
#include ctimeusing namespace std;int main()
{// MyData为测试文件,大小为1G// linux可执行truncate -s 1G MyData命令生成大文件uint64_t start std::chrono::duration_caststd::chrono::microseconds(std::chrono::system_clock::now().time_since_epoch()).count();// 创建文件HANDLE hFile CreateFile(LD://MyData,GENERIC_READ | GENERIC_WRITE,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);if (INVALID_HANDLE_VALUE hFile){cout CreateFile fail endl;return -1;}// 创建一个文件映射内核对象HANDLE hFileMapping CreateFileMapping(hFile,nullptr,PAGE_READWRITE,0,0,nullptr);if (nullptr hFileMapping){cout CreateFileMapping fail endl;CloseHandle(hFile);return -1;}// 将文件数据映射到进程的地址空间char* mapData (char*)MapViewOfFile(hFileMapping,FILE_MAP_ALL_ACCESS,0,0,0);if (nullptr mapData){cout MapViewOfFile fail endl;CloseHandle(hFileMapping);CloseHandle(hFile);return -1;}// 数据拷贝char* myBuf mapData;// 计算时间uint64_t end std::chrono::duration_caststd::chrono::microseconds(std::chrono::system_clock::now().time_since_epoch()).count(); uint64_t duration end - start; // 微妙差cout duration: duration endl;UnmapViewOfFile(myBuf);CloseHandle(hFileMapping);CloseHandle(hFile);system(pause);return 0;
}执行结果
1G的文件完成文件映射需要143微妙。 linux实例
#include iostream
#include sys/mman.h
#include sys/types.h
#include sys/stat.h
#include sys/fcntl.h
#include errno.h
#include string.h
#include stdio.h
#include stdlib.h
#include unistd.h
#include chrono
#include ctime
using namespace std;#define MY_FILE_PATH ./MyDatasize_t get_file_size(const char *file_path)
{struct stat buf;if (stat(file_path, buf) 0) {printf(%s[%d]:%s, __FUNCTION__, __LINE__, strerror(errno));return -1;}return buf.st_size;
}int main()
{// 执行truncate -s 1G MyData命令生成大文件uint64_t start std::chrono::duration_caststd::chrono::microseconds(std::chrono::system_clock::now().time_since_epoch()).count();// 打开文件int fd open(MY_FILE_PATH, O_RDWR|O_CREAT, S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH);if (-1 fd) {cout open failed,error: strerror(errno) endl;;return -1;}// 获取文件大小size_t filelen get_file_size(MY_FILE_PATH);if (-1 (int)filelen) {cout get file size failed endl;return -1;}cout filesize filelen endl;// 开始映射void* result mmap(0, filelen, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);if (result (void *)-1) {cout mmap failed,error: strerror(errno) endl;return -1;}// 计算时间uint64_t end std::chrono::duration_caststd::chrono::microseconds(std::chrono::system_clock::now().time_since_epoch()).count();uint64_t duration end - start; // 微妙差cout duration: duration endl; // 取消文件映射munmap(result, filelen);// 关闭文件句柄close(fd);return 0;
}执行结果
# 1G文件完成映射耗时270微妙
[rootlocalhost debug.x64-linux]# ./testFileMapping
filesize 1073741824
duration:270
[rootlocalhost debug.x64-linux]#