关于内存映射来修改文件,并改变文件的大小

 内存映射是为了方便多个进程间的共同开发从而共享一段内存,但是,它还有一个其他功能,那就是修改文件

在内存映射之前,首先我们需要用 CreatFile()来打开文件,如果我们需要对文件进行修改的话,第二个关键函数必须设置;


hFile=::CreateFile(lpFilename,GENERIC_WRITE|GENERIC_READ ,NULL,NULL,OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,0);


接下来就是获取文件大小,if ( INVALID_FILE_SIZE == ( mapp.dwSize=GetFileSize(hFile,NULL)) )  如果相等就是获取错误了。(获取文件大小很关键,下面我会提到)


然后就是经典的CreateFileMapping()来映射文件到内存了, 这个函数共有6个参数,楼主在之前修改文件的时候是读取文件,然后对文件字符串加密,但是加密后的体积比原文件大,这样的话我在写入的时候总是出现问题,后来仔细看了MSDN才发现,猫腻就在这个函数,它的第五个跟第六个函数告诉我们我们要映射文件的高32位的最大值,与低32位的最小值,如果两个都为零的话,它默认映射的大小就是原文件的大小,所以你在试图修改它的映射文件并把它映射回去的时候,会出现比原文件大的情况,这样就出现问题了,所有,我们在映射文件到到内存之前,最好求出我们修改后的文件大小,给CreateFileMapping();



最后就是获取我们映射到内存的基地址了,

ImageBase=::MapViewOfFile(hMapping,FILE_MAP_WRITE,0,0,0);   


还有 ,别忘了关闭句柄,CloseHandle


上例子一个,与君共勉


// 映射文件到内存  输入文件名,返回映射内存的基址
LPVOID LoadFileR(LPTSTR lpFilename, DWORD  dwSize)
{
	HANDLE hFile;
	HANDLE hMapping;
	LPVOID ImageBase;
	hFile=::CreateFile(lpFilename,GENERIC_WRITE|GENERIC_READ ,NULL,NULL,OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL,0);   // 打开一个文件,获取文件句柄  设置属性为可读可写
	if (NULL == hFile)
	{
		return NULL;
	}


	hMapping=::CreateFileMapping(hFile,NULL,PAGE_READWRITE ,0,dwSize,NULL);      // 映射文件到内存 设置内存为可写

	if (NULL == hMapping)
	{
		int i = GetLastError();
		::CloseHandle(hFile);
		return NULL;
	}
	ImageBase=::MapViewOfFile(hMapping,FILE_MAP_WRITE,0,0,0);   // 获取映射的内存基址
	CloseHandle(hFile);
	CloseHandle(hMapping);

	return ImageBase;

}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
内存映射文件是一种将文件映射到进程的虚拟地址空间中的技术,它可以让程序直接访问磁盘上的文件,就好像访问内存一样。当我们需要读取或写入大量数据时,使用内存映射文件可以提高IO性能,因为它避免了频繁的磁盘IO操作和缓存的使用。 内存映射文件的基本思路是将一个文件或一部分文件映射到进程的虚拟地址空间中,这个虚拟地址空间就成为了文件的一个镜像。在进程中,我们可以像访问内存一样访问这个虚拟地址空间,对这个虚拟地址空间的读写操作会自动映射到磁盘上的文件中。当我们修改了这个虚拟地址空间的数据时,内核会自动将这些修改同步到磁盘上的文件中。 在Linux中,可以使用mmap()系统调用来实现内存映射文件。mmap()函数可以将一段虚拟地址空间映射到一个文件描述符所表示的文件中。mmap()函数的原型如下: ``` void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); ``` 其中,addr是期望映射的虚拟地址空间的起始地址,如果addr为NULL,则由系统自动分配一个地址;length是映射的长度;prot是内存保护标志,用于指定映射区域的访问权限;flags是控制映射区域的各种属性;fd是文件描述符;offset是文件中的偏移量。 使用内存映射文件时需要注意以下几点: 1. 内存映射文件需要占用进程的虚拟地址空间,因此需要注意虚拟地址空间的大小; 2. 内存映射文件需要和文件描述符一起使用,因此需要注意文件描述符的打开和关闭; 3. 内存映射文件修改的数据需要及时同步到磁盘上,因此需要注意数据同步的方式和时机; 4. 内存映射文件的使用需要考虑数据的安全性,避免出现数据损坏或数据丢失的情况。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值