gpt4 book ai didi

c++ - 写入内存映射文本文件并打印 NULL 直到映射内存末尾

转载 作者:行者123 更新时间:2023-11-30 18:35:10 28 4
gpt4 key购买 nike

在此代码中,我将一些文本写入内存映射文本文件。数据已成功写入文件,但是当我用记事本打开它时,写入数据后,“NULL”被重复写入到映射内存限制,该限制大于我写入的文本。

可能的原因是什么?

pLogMsg = (char*)calloc(1024,sizeof(char));
printf("[INFO] entering logger writeback thread\n");

log_file = CreateFile (TEXT("one.txt"), // Open one.txt.
GENERIC_READ | GENERIC_WRITE, // Open for reading and writing
FILE_SHARE_WRITE, // file share
NULL, // No security
OPEN_ALWAYS, // Open or create
FILE_ATTRIBUTE_NORMAL, // Normal file
NULL); // No template file
if (log_file == INVALID_HANDLE_VALUE)
{
printf("%d [ERR] cant open file GLE %d\n",GetCurrentThreadId(),GetLastError());
return -1;
}
hMapping = CreateFileMapping( log_file, 0, PAGE_READWRITE, 0,4096 ,0 );
if (hMapping == INVALID_HANDLE_VALUE)
{
printf("%d [ERR] cant create file mapping %d\n",GetCurrentThreadId(),GetLastError());
return -1;
}
pFileData = (CHAR*)MapViewOfFile( hMapping, FILE_MAP_ALL_ACCESS, 0,0, 0 );
if (pFileData == NULL)
{
printf("%d [ERR] cant mapview of file %d\n",GetCurrentThreadId(),GetLastError());
return -1;
}
pLogMsg = LogPrint();//returns a null terminated string
memcpy(pFileData,pLogMsg,strlen(pLogMsg));
pFileData += strlen(pLogMsg);
free(pLogMsg);

最佳答案

首先,CreateFileMappingMapViewOfFile 对于日志文件来说,这是一个糟糕的解决方案。您需要使用 FILE_APPEND_DATA 访问权限创建/打开文件,而不是 GENERIC_READ | GENERIC_WRITE - 所以调用必须如下所示:

HANDLE log_file = CreateFileW(L"one.txt", 
FILE_APPEND_DATA,
FILE_SHARE_WRITE|FILE_SHARE_READ,
NULL,
OPEN_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL);

在这种情况下,您使用FILE_APPEND_DATASYNCHRONIZE打开文件(因为没有FILE_FLAG_OVERLAPPED):

If the caller sets only the FILE_APPEND_DATA and SYNCHRONIZE flags, it can write only to the end of the file, and any offset information about write operations to the file is ignored. The file will automatically be extended as necessary for this type of operation.

此后您需要通过WriteFile进行日志 - 它将自动附加到文件末尾。这正是日志文件所需要的。

但是,如果要使用 CreateFileMappingMapViewOfFile - 首先 CreateFileMapping 出错时返回 0,因此请检查if (hMapping == INVALID_HANDLE_VALUE) 错误

如果您想更改文件大小 - 您需要使用此 SetFileInformationByHandleFileEndOfFileInfo (vista+)或 NtSetInformationFile使用 FileEndOfFileInformation (到处都可以使用,如何不难理解 SetFileInformationByHandle 只是 NtSetInformationFileZwSetInformationFile 上非常薄的外壳(在用户模式这是相同的功能))。使用 SetFilePointer 后跟 SetEndOfFile 也是可能的,但不好且不是有效的选择 - 您将在 src 代码中进行 2 个调用,而不是单个调用。在二进制文件中 - 你会遇到更糟糕的情况:首先设置文件位置,SetEndOfFile读取该文件位置,最后使用该位置调用NtSetInformationFile。所以 3 个调用而不是 1 个。并假设在 SetFilePointerSetEndOfFile 调用之间没有人更改文件位置(在此句柄上)

但需要清楚地了解,只有在取消映射 View 并关闭部分后,才能使用 FileEndOfFileInfo 调用 SetFileInformationByHandle 。否则您会收到错误 ERROR_USER_MAPPED_FILE (STATUS_USER_MAPPED_FILE )

If CreateFileMapping is called to create a file mapping object for hFile, UnmapViewOfFile must be called first to unmap all views and call CloseHandle to close the file mapping object before you can call SetEndOfFile.

关于c++ - 写入内存映射文本文件并打印 NULL 直到映射内存末尾,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47651573/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com