Windows下空txt文件内存映射报错1006求助(附Linux实现代码)
问题:Windows下创建空文件内存映射时出现错误1006
将尚未写入数据的.txt文件映射到内存时,调用CreateFileMapping函数持续返回错误1006。Linux平台下的文件内存映射功能已开发完成,但移植到Windows平台时遇到此问题,无法排查解决。
Linux平台实现代码
// Open the output file int output_file = open(argv[2], O_CREAT | O_RDWR, S_IRUSR | S_IWUSR); if (!output_file) { printf("Unable to create file."); exit(1); } // Get the size of the output file size_t output_file_size = strlen(input_data_without_comments); // Set length to file ftruncate(output_file, output_file_size); // Map the output file into memory char *output_data = mmap(NULL, output_file_size, PROT_WRITE, MAP_SHARED, output_file, 0); if (output_data == MAP_FAILED) { printf("Error: failed to map output file\n"); exit(1); }
Windows平台当前实现代码
// Open the output file printf("Open the output file\n"); HANDLE output_file = CreateFile(argv[2], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (output_file == INVALID_HANDLE_VALUE) { _tprintf(_T("Error: could not open output file '%s'\n"), argv[2]); exit(1); } // Initializing variables for output length DWORD output_file_size = 0; DWORD high_output_file_size = 0; // Get length of the output file output_file_size = GetFileSize(output_file, &high_output_file_size); printf("Size of the output_file: %d\n", output_file_size); // Output file mapping printf("Output file mapping\n"); HANDLE output_file_mapping = CreateFileMapping(output_file, NULL, PAGE_READWRITE, 0, 0, NULL); if (output_file_mapping == NULL) { _tprintf(_T("Unable to create file mapping (output_file)\n")); _tprintf(_T("Last error was: %i"), GetLastError()); exit(1); } // Set length to file printf("Set length to file\n"); SetFilePointer(output_file, output_file_size, NULL, FILE_BEGIN); SetEndOfFile(output_file); // Map the output file into memory printf("Map the output file into memory\n"); char *output_data = MapViewOfFile(output_file_mapping, FILE_MAP_WRITE, 0, 0, output_file_size); if (output_data == NULL) { printf("Error: failed to map output file\n"); exit(1); }
问题原因及修复方案
核心问题
错误1006对应ERROR_FILE_INVALID,根源是操作顺序错误:
- Linux流程是:打开文件 → 确定目标大小 → 调整文件大小 → 创建内存映射,这是正确的顺序,因为创建映射时文件已经有了有效大小。
- Windows当前流程是:打开空文件 → 获取空文件大小(0) → 创建文件映射(基于0大小的文件) → 调整文件大小,此时创建映射时文件是0字节,导致
CreateFileMapping失败。
另外,Windows代码中错误地用GetFileSize获取空文件的大小(得到0),而非使用input_data_without_comments的长度,这也是逻辑错误。
修复后的Windows代码
// Open the output file printf("Open the output file\n"); HANDLE output_file = CreateFile(argv[2], GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, 0, NULL); if (output_file == INVALID_HANDLE_VALUE) { _tprintf(_T("Error: could not open output file '%s'\n"), argv[2]); exit(1); } // 获取要写入的数据长度(和Linux逻辑一致) DWORD output_file_size = strlen(input_data_without_comments); printf("Target size of the output_file: %d\n", output_file_size); // 先调整文件大小到目标长度 printf("Set length to file\n"); if (SetFilePointer(output_file, output_file_size, NULL, FILE_BEGIN) == INVALID_SET_FILE_POINTER) { _tprintf(_T("SetFilePointer failed\n")); exit(1); } if (!SetEndOfFile(output_file)) { _tprintf(_T("SetEndOfFile failed\n")); exit(1); } // 再创建文件映射 printf("Output file mapping\n"); HANDLE output_file_mapping = CreateFileMapping(output_file, NULL, PAGE_READWRITE, 0, output_file_size, NULL); if (output_file_mapping == NULL) { _tprintf(_T("Unable to create file mapping (output_file)\n")); _tprintf(_T("Last error was: %i"), GetLastError()); exit(1); } // 映射文件到内存 printf("Map the output file into memory\n"); char *output_data = MapViewOfFile(output_file_mapping, FILE_MAP_WRITE, 0, 0, output_file_size); if (output_data == NULL) { printf("Error: failed to map output file\n"); exit(1); }
关键修复点
- 调整操作顺序:先设置文件大小,再创建文件映射,确保创建映射时文件已有有效长度。
- 修正文件大小来源:直接使用
input_data_without_comments的长度作为目标文件大小,而非读取空文件的大小。 - 可选优化:在
CreateFileMapping中显式指定映射大小(第五个参数),避免依赖文件当前大小,逻辑更清晰。
内容的提问来源于stack exchange,提问作者Michael Hajný
相关产品推荐
相关产品推荐

