用内存映射文件后的文件应该怎么保存

vincent_1011 2009-02-18 05:11:20
当使用CreateMapFile操作文件的时候,由于要指定对齐

但实际上最后那个数据只用到一页中的几个字节,那多出来的不是点空间了吗?

怎么样做到保存的时候文件大小是实际数据大小?
...全文
331 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
VirGhost 2009-02-19
  • 打赏
  • 举报
回复
我好像明白点你的意思了,这样描述你看行不行。

假如说在磁盘上创建了一个文本文件test.txt,在里面手动写入ab两个字符,保存关闭文件,这时查看文件属性,大小2byte,占用磁盘空间4KB,不用理会这个4KB。

在程序中打开该文件
HANDLE hFile = ::CreateFile(...)

获得文件大小,得到的是2,即2byte
DWORD dwFileSize = ::GetFileSize(hFile, NULL);

预测一下你想加入的字节数
DWORD dwAppend = 5;

这时可以创建map对象了,注意大小为dwFileSize + dwAppend
HANDLE hFileMap = ::CreateFileMapping(hFile, NULL, PAGE_READWRITE, 0, dwFileSize + dwAppend, NULL);

创建映射窗口,最后一个参数为0或者dwFileSize + dwAppend
PBYTE pbFile = (PBYTE)::MapViewOfFile(hFileMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);

下面就可以使用pbFile任意添加数据了(注意保持dwFileSize跟着变),例如
pbFile[dwFileSize++] = 'q';
pbFile[dwFileSize++] = 'w';
pbFile[dwFileSize++] = 'e';

假如添加了3个数据后不想再添加了,先释放资源
::UnmapViewOfFile(pbFile);
::CloseHandle(hFileMap);

再设置文件大小为正确的大小
::SetFilePointer(hFile, dwFileSize, NULL, FILE_BEGIN);
::SetEndOfFile(hFile);
::CloseHandle(hFile);

最后文件的内容是"abqwe",大小为5byte(原先的2byte和后加入的3byte)。
始终不用理会那个4KB,OK不,有什么不对的请指正。
KHacker_001 2009-02-18
  • 打赏
  • 举报
回复
学习中
vincent_1011 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用 6 楼 caremsi 的回复:]
学习了。
[/Quote]

晕死你,问题都没解决,你学习个啥,
caremsi 2009-02-18
  • 打赏
  • 举报
回复
学习了。
vincent_1011 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 VirGhost 的回复:]
引用楼主 vincent_1011 的帖子:
当使用CreateMapFile操作文件的时候,由于要指定对齐



调用CreateFileMapping时貌似没要求对齐吧
[/Quote]
但问题我是要追加数据啊,所以肯定要指定一个大小,现在出来这2个情况我不太清,

不知道能不能解释下,就是文件的大小和其占用空间

占用空间就要是4K倍数。因为我刚刚用CreateFileMapping创建一个100K文件,但是占用空间就是4K
VirGhost 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用楼主 vincent_1011 的帖子:]
当使用CreateMapFile操作文件的时候,由于要指定对齐

[/Quote]

调用CreateFileMapping时貌似没要求对齐吧
vincent_1011 2009-02-18
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 VirGhost 的回复:]
在CreateMapFile前先调用GetFileSize获得文件大小,Unmap以后调用SetFilePointer恢复大小,第二个参数就是你刚才获得的文件大小,最后调用SetEndOfFile
[/Quote]3

CreateMapfile之前获取的大小有啥用,因为我弄的是追加数据,但追加的数据不超过一页。

不知道咋办好。另外MapViewOfFile里面追加的数据需要在边界对齐地方开始,这样又浪费了不少空间。

不知道大家用这些函数的时候是怎么解决的
vincent_1011 2009-02-18
  • 打赏
  • 举报
回复
原来就是这2个函数啊?那这SetFilePointer,可是我发现也有人用来读数据啊?

因为我们平时打开文件的时候不是默认有一个读或者写指针是在文件的第一个字节的吗?和这个SetFilePointer

有区别没?
VirGhost 2009-02-18
  • 打赏
  • 举报
回复
在CreateMapFile前先调用GetFileSize获得文件大小,Unmap以后调用SetFilePointer恢复大小,第二个参数就是你刚才获得的文件大小,最后调用SetEndOfFile

69,373

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧