如何用Win32 API的CreateFile实现C标准库r+b模式的指定偏移覆写
解决Win32 API实现C标准库
r+b模式覆写文件的问题 你的代码核心问题在于CreateFile的创建方式参数错误,CREATE_ALWAYS会直接覆盖或创建新文件,这和C标准库r+b(打开已存在文件进行读写更新)的行为完全不符。以下是等效的实现代码:
正确的Win32 API代码
DWORD offset = 0x44; // 对应原代码的偏移量 HANDLE hFile = CreateFile( pszFileName, GENERIC_WRITE | GENERIC_READ, // 对应r+b的读写权限 0, // 独占访问,和fopen默认行为一致 NULL, // 默认安全属性 OPEN_EXISTING, // 仅打开已存在的文件,对应r+b的行为(文件不存在则失败) FILE_ATTRIBUTE_NORMAL, // 普通文件属性 NULL // 无模板文件 ); if (hFile != INVALID_HANDLE_VALUE) { // 设置文件指针到指定偏移 SetFilePointer(hFile, offset, NULL, FILE_BEGIN); DWORD bytesWritten; // 写入数据,需传入bytesWritten指针确认写入完整性 if (WriteFile(hFile, buffer, 8, &bytesWritten, NULL) && bytesWritten == 8) { // 写入成功 } CloseHandle(hFile); }
参数说明(对应C标准库r+b模式)
- 访问权限:
GENERIC_WRITE | GENERIC_READ,对应r+b允许读写文件的特性;若仅需写入,GENERIC_WRITE也可,但保持和标准库行为一致更稳妥。 - 创建方式:
OPEN_EXISTING是关键,该参数会打开已存在的文件,若文件不存在则返回INVALID_HANDLE_VALUE,完全匹配fopen("r+b")的行为。你之前使用的CREATE_ALWAYS会直接清空现有文件或创建新文件,这就是导致覆写整个文件的原因。 - 文件指针操作:
SetFilePointer对应fseek,FILE_BEGIN对应SEEK_SET,作用完全一致。 - WriteFile注意事项:务必传入
bytesWritten指针,用来确认实际写入的字节数是否符合预期,避免因磁盘空间不足等问题导致写入不完整。
可选调整
如果需要实现类似w+b(允许文件不存在时创建,但保留原有内容)的行为,可以将创建方式改为OPEN_ALWAYS,但这和原代码的r+b行为有差异,按需选择。
内容的提问来源于stack exchange,提问作者Jayson Gazeley
相关产品推荐
相关产品推荐

