Win32 C中内存映射文件(MMF)修改未同步到底层文件求助
Hey Jeff, let's dig into why your memory-mapped file (MMF) changes aren't syncing to the underlying disk file. From the code snippet you shared, there are a few critical gaps and misconfigurations that are likely causing the issue. Let's break this down step by step:
Key Issues in Your Current Code
1. CREATE_NEW might not be the right creation disposition
Using CREATE_NEW means the function will fail if the file already exists, but more importantly: when you create a brand-new file with this flag, its initial size is 0 bytes. A memory-mapped view of a 0-byte file gives you no writable space, so any changes you make won't be persisted (or might not even be possible to make in the first place).
2. Missing critical MMF setup steps
Your snippet only shows the CreateFile call—full MMF functionality requires additional steps to map the file to memory, handle size configuration, and explicitly sync changes to disk.
Fixed & Complete Example Code
Here's a corrected version that ensures changes are synced to the disk file:
#include "stdafx.h" #include <Windows.h> #include <tchar.h> int main() { wchar_t szfilename[] = L"c:\\temp\\mmf.txt"; // Use OPEN_ALWAYS to create the file if it doesn't exist, or open it if it does HANDLE hFile = CreateFile( szfilename, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_ALWAYS, // Replaced CREATE_NEW with OPEN_ALWAYS FILE_ATTRIBUTE_NORMAL, NULL); if (hFile == INVALID_HANDLE_VALUE) { _tprintf(L"CreateFile failed with error %d\n", GetLastError()); return 1; } // Set a valid file size (critical for new files) LARGE_INTEGER fileSize; fileSize.QuadPart = 4096; // 4KB example size if (!SetFilePointerEx(hFile, fileSize, NULL, FILE_BEGIN) || !SetEndOfFile(hFile)) { _tprintf(L"Failed to set file size, error %d\n", GetLastError()); CloseHandle(hFile); return 1; } // Create the file mapping object HANDLE hMapFile = CreateFileMapping( hFile, NULL, PAGE_READWRITE, // Read-write access for the mapped view 0, 0, NULL); if (hMapFile == NULL) { _tprintf(L"CreateFileMapping failed with error %d\n", GetLastError()); CloseHandle(hFile); return 1; } // Map the file to a memory view LPVOID lpMapAddress = MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0); if (lpMapAddress == NULL) { _tprintf(L"MapViewOfFile failed with error %d\n", GetLastError()); CloseHandle(hMapFile); CloseHandle(hFile); return 1; } // Modify the mapped memory wcscpy_s((wchar_t*)lpMapAddress, 4096/sizeof(wchar_t), L"Hello, Persistent MMF!"); // Explicitly flush changes to disk (critical for immediate sync) if (!FlushViewOfFile(lpMapAddress, wcslen((wchar_t*)lpMapAddress)*sizeof(wchar_t))) { _tprintf(L"FlushViewOfFile failed with error %d\n", GetLastError()); } // Clean up all handles and mappings UnmapViewOfFile(lpMapAddress); CloseHandle(hMapFile); CloseHandle(hFile); return 0; }
Critical Notes for Sync Success
- Explicitly flush changes: While
UnmapViewOfFilewill eventually sync changes to disk, callingFlushViewOfFileensures your modifications are written immediately, which is essential if you need the file to reflect changes right away. - Set a valid file size: For new files, you must define a non-zero size before creating the mapping—otherwise, there's no space to write data to.
- Proper handle cleanup: Always close the mapped view, file mapping handle, and file handle in order. Leaking handles can prevent disk sync or cause resource issues.
内容的提问来源于stack exchange,提问作者Jeff

