一、项目背景详细介绍
在 Windows 平台的 C++ 工程开发中,除了使用C++ 标准文件流(fstream),我们还经常会直接使用Windows API来进行底层文件操作。
其中,WriteFile是 Windows 平台上:
最核心、最底层、最常用的文件写入 API
典型应用场景包括:
高性能日志系统
驱动 / 服务程序
Windows 专用工具
与 C 运行库(CRT)解耦的程序
大文件、高频写入场景
与
ReadFile对应的二进制 I/O网络 / 管道 / 设备文件写入
与std::ofstream相比,WriteFile具有以下特点:
| 对比项 | WriteFile | fstream |
|---|---|---|
| 平台 | Windows 专用 | 跨平台 |
| 层级 | 操作系统 API | C++ 抽象 |
| 性能 | 更高 | 略低 |
| 控制力 | 极强 | 一般 |
| 用途 | 工程 / 系统级 | 应用级 |
本项目将系统性讲解:
如何在 C++ 中使用 Windows 的 WriteFile 函数安全、正确地写文件
二、项目需求详细介绍
2.1 功能性需求
使用 Windows API 创建 / 打开文件
使用
WriteFile写入数据支持文本与二进制数据
正确处理返回值与错误
确保资源正确释放
2.2 非功能性需求
仅依赖 Windows API(
<Windows.h>)不使用 C++ 文件流
不依赖第三方库
代码清晰、注释完整
工程可直接复用
2.3 平台说明
⚠️ 本项目仅适用于 Windows 平台
三、相关技术详细介绍
3.1 Windows 文件句柄(HANDLE)
在 Windows API 中:
文件不是“对象”
而是通过句柄(HANDLE)操作
文件操作流程通常为:
CreateFile → WriteFile → CloseHandle
3.2CreateFile简要说明
HANDLE CreateFile( LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile );
常用参数:
GENERIC_WRITE:写权限CREATE_ALWAYS:不存在则创建,存在则覆盖OPEN_ALWAYS:不存在则创建,存在则打开
3.3WriteFile函数原型
BOOL WriteFile( HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped );
关键点:
写入的是字节
返回值表示是否成功
实际写入字节数通过指针返回
四、实现思路详细介绍
整体实现步骤如下:
使用
CreateFile打开 / 创建文件准备待写入的数据缓冲区
调用
WriteFile写入数据检查返回值与写入字节数
使用
CloseHandle关闭文件
该方式:
不受文本 / 二进制影响
不进行任何编码转换
工程行为完全可控
五、完整实现代码
/******************************************************** * 文件名:write_file_winapi.cpp * 功能:使用 Windows API 的 WriteFile 函数写文件 * 说明: * 1. 使用 CreateFile 创建/打开文件 * 2. 使用 WriteFile 写入数据 * 3. 使用 CloseHandle 释放资源 ********************************************************/ #include <windows.h> #include <iostream> #include <string> /** * @brief 使用 WriteFile 写文件 * @param fileName 文件路径 * @param data 要写入的数据 * @return true 写入成功,false 写入失败 */ bool writeFileByWinAPI(const std::string& fileName, const std::string& data) { // 创建或覆盖文件 HANDLE hFile = CreateFileA( fileName.c_str(), // 文件路径 GENERIC_WRITE, // 写权限 0, // 不共享 NULL, // 默认安全属性 CREATE_ALWAYS, // 存在则覆盖,不存在则创建 FILE_ATTRIBUTE_NORMAL, // 普通文件 NULL // 模板文件 ); if (hFile == INVALID_HANDLE_VALUE) { std::cerr << "CreateFile 失败,错误码:" << GetLastError() << std::endl; return false; } DWORD bytesWritten = 0; // 写入数据 BOOL result = WriteFile( hFile, // 文件句柄 data.c_str(), // 数据缓冲区 static_cast<DWORD>(data.size()), // 写入字节数 &bytesWritten, // 实际写入字节数 NULL // 同步写入 ); if (!result) { std::cerr << "WriteFile 失败,错误码:" << GetLastError() << std::endl; CloseHandle(hFile); return false; } // 校验写入字节数 if (bytesWritten != data.size()) { std::cerr << "写入字节数不完整!" << std::endl; CloseHandle(hFile); return false; } // 关闭文件句柄 CloseHandle(hFile); return true; } int main() { std::string fileName = "winapi_test.txt"; std::string content = "Hello Windows WriteFile!\r\n第二行内容"; if (writeFileByWinAPI(fileName, content)) { std::cout << "WriteFile 写文件成功!" << std::endl; } else { std::cout << "WriteFile 写文件失败!" << std::endl; } return 0; }六、代码详细解读(仅解读方法作用)
6.1writeFileByWinAPI
使用
CreateFileA创建 / 打开文件调用
WriteFile将字节数据写入文件通过
bytesWritten校验写入完整性使用
CloseHandle释放系统资源
6.2main函数
构造测试文件名与写入内容
调用封装好的写文件函数
输出执行结果
七、项目详细总结
通过该项目,你已经系统掌握:
Windows 文件句柄(HANDLE)的概念
CreateFile/WriteFile/CloseHandle的标准用法Windows API 写文件的完整流程
如何进行错误码检查与工程级校验
Windows 底层文件 I/O 的正确打开方式
该实现:
性能高
控制力强
工程实战性极高
适合系统级与工具级程序
八、项目常见问题及解答
Q1:WriteFile 能写二进制文件吗?
可以。WriteFile永远以字节为单位。
Q2:是否会进行编码转换?
不会。
写什么字节,就存什么字节。
Q3:为什么要手动判断bytesWritten?
因为 API 只保证“尽力写”,
工程中必须校验完整性。
Q4:与ofstream相比有什么优势?
更高性能
更底层控制
可用于设备、管道、Socket