网站模板没有html文件下载,免费浪漫网页制作网站,网站建设策划目的及过程,公司注册名字审核网ReadFile 函数概述
ReadFile 是 Windows API 函数#xff0c;用于从文件或设备#xff08;如串口、硬盘等#xff09;中读取数据。它是同步和异步 I/O 操作的基础函数。 函数原型
BOOL ReadFile(_In_ HANDLE hFile, // 文件或设备句柄_Out_write…ReadFile 函数概述
ReadFile 是 Windows API 函数用于从文件或设备如串口、硬盘等中读取数据。它是同步和异步 I/O 操作的基础函数。 函数原型
BOOL ReadFile(_In_ HANDLE hFile, // 文件或设备句柄_Out_writes_bytes_to_opt_(nNumberOfBytesToRead, *lpNumberOfBytesRead) LPVOID lpBuffer, // 缓冲区_In_ DWORD nNumberOfBytesToRead, // 预期读取的字节数_Out_opt_ LPDWORD lpNumberOfBytesRead, // 实际读取的字节数会根据_In_ DWORD返回给他_Inout_opt_ LPOVERLAPPED lpOverlapped // 异步操作参数
);参数详解
1. HANDLE hFile
含义表示需要读取数据的目标。 可以是文件句柄通过 CreateFile 打开或设备句柄如串口 COM1。例如读取串口数据时通过 CreateFile 获得串口句柄。
2. LPVOID lpBuffer
含义指向缓冲区的指针ReadFile 将读取的数据存储到该缓冲区中。大小要求缓冲区大小应至少等于 nNumberOfBytesToRead以避免越界。类型LPVOID可转换为任意指针类型如 char*。
3. DWORD nNumberOfBytesToRead
含义预期读取的字节数ReadFile 尝试从文件或设备读取该数量的数据。注意 如果设备中数据不足ReadFile 可能返回成功但实际读取的字节数会少于此值存储在 lpNumberOfBytesRead 中。
4. LPDWORD lpNumberOfBytesRead
含义指向 DWORD 类型变量的指针用于接收实际读取的字节数。可选性 如果为 nullptr表示调用方不关心读取了多少字节不推荐。 返回值含义 函数执行成功后该变量存储实际读取的字节数。
5. LPOVERLAPPED lpOverlapped
含义指向 OVERLAPPED 结构的指针用于异步操作。同步与异步 nullptr表示同步操作ReadFile 会阻塞直到读取完成或超时。非 nullptr表示异步操作ReadFile 会立即返回读取操作会在后台完成。 返回值
BOOL 类型 TRUE读取成功。FALSE读取失败调用 GetLastError 获取错误代码。 常见错误 ERROR_HANDLE_EOF已到达文件末尾EOF。ERROR_IO_PENDING对于异步操作表示读取请求已提交但尚未完成。 函数用途
ReadFile 广泛用于以下场景
文件读取从文件系统中读取内容。串口通信读取串口COM数据常用于嵌入式设备通信。网络通信通过设备接口读取基于设备接口的网络数据。传感器数据读取从硬件传感器中读取数据。 示例 1从文件读取数据
从文件中读取内容并打印到控制台
#include windows.h
#include iostreamint main() {// 打开文件HANDLE hFile CreateFile(example.txt, // 文件路径GENERIC_READ, // 读取权限0, // 共享模式NULL, // 安全属性OPEN_EXISTING, // 打开已存在的文件FILE_ATTRIBUTE_NORMAL, // 属性NULL // 模板文件句柄);if (hFile INVALID_HANDLE_VALUE) {std::cerr 无法打开文件错误代码 GetLastError() std::endl;return 1;}// 读取数据char buffer[128] {0}; // 数据缓冲区DWORD bytesRead 0; // 实际读取的字节数if (ReadFile(hFile, buffer, sizeof(buffer) - 1, bytesRead, NULL)) {std::cout 成功读取 bytesRead 字节 std::endl;std::cout buffer std::endl;} else {std::cerr 读取失败错误代码 GetLastError() std::endl;}// 关闭文件CloseHandle(hFile);return 0;
}示例 2串口数据读取
从串口如 COM2读取数据
#include windows.h
#include iostreamint main() {// 打开串口HANDLE hSerial CreateFile(COM2, // 串口名称GENERIC_READ, // 读取权限0, // 共享模式NULL, // 安全属性OPEN_EXISTING, // 打开已存在的设备0, // 属性NULL // 模板文件句柄);if (hSerial INVALID_HANDLE_VALUE) {std::cerr 无法打开串口错误代码 GetLastError() std::endl;return 1;}// 设置串口参数波特率、数据位等DCB dcb {0};//Device Control Blockdcb.DCBlength sizeof(DCB);GetCommState(hSerial, dcb);dcb.BaudRate CBR_9600;dcb.ByteSize 8;dcb.Parity NOPARITY;dcb.StopBits ONESTOPBIT;SetCommState(hSerial, dcb);// 读取数据char buffer[128] {0};DWORD bytesRead 0;if (ReadFile(hSerial, buffer, sizeof(buffer) - 1, bytesRead, NULL)) {std::cout 成功读取 bytesRead 字节 std::endl;for (DWORD i 0; i bytesRead; i) {std::cout 0x std::hex static_castint(buffer[i]) ;}std::cout std::endl;} else {std::cerr 读取失败错误代码 GetLastError() std::endl;}// 关闭串口CloseHandle(hSerial);return 0;
}异步模式的应用
如果需要非阻塞读取可以使用 OVERLAPPED 结构
OVERLAPPED overlapped {0};
overlapped.hEvent CreateEvent(NULL, TRUE, FALSE, NULL);BOOL result ReadFile(hFile, buffer, sizeof(buffer), bytesRead, overlapped);
if (!result GetLastError() ERROR_IO_PENDING) {// 等待异步操作完成WaitForSingleObject(overlapped.hEvent, INFINITE);GetOverlappedResult(hFile, overlapped, bytesRead, FALSE);
}总结
ReadFile 的作用
从文件或设备读取数据支持同步和异步模式。
典型应用
文件操作读取文本或二进制文件。串口通信读取嵌入式设备数据。网络设备读取基于接口的网络数据。
优点
支持异步 I/O提高程序性能。适用于广泛的文件和设备操作场景。
注意事项
缓冲区大小要足够大以避免数据截断。在串口和异步模式中需额外配置超时和事件处理机制。
补充 1 关于DBC
DCB dcb {0}; 是一个用于初始化并配置串口通信参数的结构体。在 Windows API 中DCBDevice Control Block结构用于描述串口通信的控制设置例如波特率、数据位、停止位、校验位等。 DCB 结构的定义
typedef struct _DCB {DWORD DCBlength; // 结构体的大小字节DWORD BaudRate; // 波特率如 9600、115200DWORD fBinary: 1; // 是否使用二进制模式DWORD fParity: 1; // 是否启用校验位DWORD fOutxCtsFlow: 1; // 是否启用 CTS 流控制DWORD fOutxDsrFlow: 1; // 是否启用 DSR 流控制DWORD fDtrControl: 2; // DTR 控制流设置DWORD fDsrSensitivity: 1; // DSR 灵敏度DWORD fTXContinueOnXoff: 1; // 接收 XOFF 后是否继续传输DWORD fOutX: 1; // 是否启用 XON/XOFF 流控制输出DWORD fInX: 1; // 是否启用 XON/XOFF 流控制输入DWORD fErrorChar: 1; // 是否替换错误字符DWORD fNull: 1; // 是否丢弃 NULL 字节DWORD fRtsControl: 2; // RTS 控制流设置DWORD fAbortOnError: 1;// 是否在错误时中止读/写操作DWORD fDummy2: 17; // 保留位WORD wReserved; // 保留字段WORD XonLim; // XON 限制WORD XoffLim; // XOFF 限制BYTE ByteSize; // 每个字节的数据位数4-8 位BYTE Parity; // 校验类型无、奇、偶、标记、空BYTE StopBits; // 停止位1、1.5 或 2 位char XonChar; // XON 字符char XoffChar; // XOFF 字符char ErrorChar; // 替换错误的字符char EofChar; // 文件结束符char EvtChar; // 事件字符WORD wReserved1; // 保留字段
} DCB, *LPDCB;补充2 影响速度的因素
ReadFile 的读取缓冲区的速度和范围没有固定的值它受到以下多个因素的影响。具体的读取速度和数据范围会因场景、设备以及系统配置而有所不同。 1. 影响 ReadFile 读取速度的因素
文件读取速度
现代 SSD几百 MB/s。HDD50-200 MB/s。
串口读取速度
受波特率限制 9600 bps约 960 字节/秒。115200 bps约 11,520 字节/秒。 调整缓冲区大小可以提升效率。
影响速度的关键点
硬件速率文件存储设备、串口波特率等。用户缓冲区大小每次读取的最大字节数。系统缓冲区通过 SetupComm 设置大小。数据可用性设备中数据是否已准备好。
通过合理调整缓冲区大小与 I/O 参数ReadFile 的速度可以优化到设备允许的上限范围。