C++ 使用文件映射

本文介绍了在C++中如何使用文件映射处理大文件,通过CreateFileA、CreateFileMappingA和MapViewOfFile等函数实现。在完成操作后,必须调用UnmapViewOfFile和CloseHandle等函数释放资源。建议使用C++11的shared_ptr定制删除器以防止资源泄露。在写入文件映射时,若文件大小未知,应根据实际写入大小调整映射,然后通过memmove函数迁移数据。

 针对大文件来说一般是以内存映射文件的方式来进行的。具体的各种原理什么的可以参考windows核心编程。这里主要说下怎么用的。

  一般情况下使用CreateFileA,CreateFileMappingA,MapViewOfFile就可以了。


hfile = CreateFileA("temp.txt", GENERIC_WRITE | GENERIC_READ, FILE_SHARE_READ, nullptr,
CREATE_ALWAYS, FILE_FLAG_SEQUENTIAL_SCAN, nullptr);
if (hfile == INVALID_HANDLE_VALUE)
return;
SECURITY_ATTRIBUTES sa;
SECURITY_DESCRIPTOR sd;
InitializeSecurityDescriptor(&sd, SECURITY_DESCRIPTOR_REVISION);
SetSecurityDescriptorDacl(&sd, TRUE, nullptr, FALSE);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = &sd;
sa.bInheritHandle = FALSE;
mapping = CreateFileMappingA(hfile, &sa, PAGE_READWRITE, 0, 1024 * 1024 * 1024, nullptr);
if (mapping == nullptr)
{
CloseHandle(hfile);
return;
}

addr = (char *)MapViewOfFile(mapping, FILE_MAP_ALL_ACCESS, 0, 0, 0);
if (addr == nullptr)
{
CloseHandle(hfile);
CloseHandle(mapping);
return;
}

使用完后要调用UnmapViewOfFile及CloseHandle等函数。如果使用c++11 可以使用shared_ptr定制删除器来防止忘记调用的情况,或者出现异常没有执行到CloseHandle那一步。

使用智能指针要包括头文件memory。shared_ptr<VOID> Pfile(hfile, [](HANDLE  p){CloseHandle(p); });


同时还有一个问题就是,如果我们创建文件映射是用来写入文件,那么我们再这之前是不可能确定知道文件的大小的。比如说我映射了一个文件大小是一个G,但是最终我写入了20M,如果我们不做任何的处理直接调用UnmapViewOfFile及CloseHandle函数那么最终生成的文件还是一个G的大小。

这个时候我们应该在调用CreateFileA生成我们最终的文件名,CreateFileMappingA时以实际写入的大小进行映射,

最后调用MapViewOfFile获取指针addr2,调用memmove(addr2,addr,readpos)将原来temp.txt文件里的内容拷贝到新的文件中即可,readpos为实际写入的数据。如果想要追加写的话在第二次调用CreateFileA时先判断文件是否存在,如果存在求出长度length,在调用CreateFileMappingA时大小为本次的实际大小加上length 调用memmove时要注意偏移量及memmove(addr2 + length,addr,readpos);



 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值