CreateFileMapping() 用于写入文件长度未知的文本
Posted
技术标签:
【中文标题】CreateFileMapping() 用于写入文件长度未知的文本【英文标题】:CreateFileMapping() for writing text whose length is unknown to file 【发布时间】:2015-02-28 11:30:31 【问题描述】:我想将文本写入文件。文本长度未知。所以我不知道要设置要使用的映射内存的大小,我将它设置为100。然后,问题出现了!字符串写入成功,但是剩余的100字节空间被NULL填充!!怎样才能避免???
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>
#include <assert.h>
void main()
HANDLE hFile2 = CreateFile("hi.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
assert(hFile2 != INVALID_HANDLE_VALUE);
// mapping..
HANDLE hMapping2 = CreateFileMapping(hFile2, NULL, PAGE_READWRITE, 0, 100, NULL);
assert(hMapping2 != NULL);
void* p2;
p2 = MapViewOfFile(hMapping2, FILE_MAP_WRITE, 0, 0, 0);
assert(p2 != NULL);
char *chp;
if(rand() % 2)
chp = "yeah!!";
else
chp = "good";
// copy
memcpy(p2, chp, strlen(chp));
// close
UnmapViewOfFile(p2);
CloseHandle(hMapping2);
CloseHandle(hFile2);
【问题讨论】:
SetEndOfFile
? msdn.microsoft.com/en-us/library/windows/desktop/…
SetFilePointer(hFile2, strlen(chp), 0, 0); SetEndOfFile(hFile2);它有效!
也许你应该使用strlen(chp)+l
,来保持nul?还有memcpy
。
在这种情况下,为什么要使用映射呢? (相对于WriteFile
)
@Mackerel:WriteFile 似乎不太可能比使用映射慢得多。我强烈怀疑你测量不正确。
【参考方案1】:
函数SetEndOfFile
会将物理文件大小设置为文件指针的当前位置。而SetFilePointer
会设置文件指针。
所以要截断文件:
CloseHandle(hMapping2); // do first
SetFilePointer(hFile2, strlen(chp), 0, 0);
SetEndOfFile(hFile2);
【讨论】:
另见How do you pre-allocate space for a file in C/C++ on Windows?以上是关于CreateFileMapping() 用于写入文件长度未知的文本的主要内容,如果未能解决你的问题,请参考以下文章
CreateFileMapping,MapViewOfFile,如何避免占用系统内存
无法释放 C++ 中 CreateFileMapping 和 MapViewOfFile 创建的共享内存
CreateFileMapping MapViewOfFile UnmapViewOfFile函数用法及示例
尝试使用 CreateFileMapping 和自定义 DACL 创建只读共享内存区域在 OpenFileMapping 中失败