Win32 API读取文件输出含随机字符的问题排查
问题原因与修复方案
问题出在你将读取到的字节数组直接当作C风格字符串输出,但ReadFile只会写入文件的原始字节内容,不会自动添加字符串终止符\0。而你通过HeapAlloc分配的堆内存是未初始化的,std::cout输出C风格字符串时会一直读取,直到遇到内存中的第一个\0才停止,后面的随机字符就是堆内存里的垃圾数据。
另外还有一个细节错误:ReadFile的返回值类型是BOOL,不是NTSTATUS,你的代码里类型匹配错了。
具体修复步骤
- 多分配1字节缓冲区:给字符串终止符
\0预留空间,避免越界 - 手动添加终止符:读取完成后,在实际读取到的字节末尾插入
\0 - 补全错误检查:文件打开、内存分配、读取操作都可能失败,必须处理这些异常情况
修改后的完整代码
HANDLE hFileRead = CreateFileA(FilePath, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); // 检查文件是否成功打开 if (hFileRead == INVALID_HANDLE_VALUE) { // 可添加错误处理逻辑,比如调用GetLastError()获取错误码 return 1; } LARGE_INTEGER fileSize = { 0 }; // 检查文件大小获取是否成功 if (!GetFileSizeEx(hFileRead, &fileSize)) { CloseHandle(hFileRead); // 错误处理 return 1; } // 多分配1字节,用于存储字符串终止符'\0' PBYTE buffer = (PBYTE)HeapAlloc(GetProcessHeap(), 0, fileSize.QuadPart + 1); // 检查内存分配是否成功 if (!buffer) { CloseHandle(hFileRead); // 错误处理 return 1; } DWORD dwBytesRead = 0; // ReadFile返回BOOL类型,修正类型错误 BOOL readSuccess = ReadFile(hFileRead, buffer, (DWORD)fileSize.QuadPart, // 注:若文件超过4GB,需分多次读取,此处适配小文件场景 &dwBytesRead, NULL); if (readSuccess) { // 在读取内容末尾添加字符串终止符 buffer[dwBytesRead] = '\0'; std::cout << buffer << "\n"; } else { // 读取失败的处理逻辑 } // 释放资源:先释放内存,再关闭文件句柄 HeapFree(GetProcessHeap(), 0, buffer); CloseHandle(hFileRead);
内容的提问来源于stack exchange,提问作者B00t
相关产品推荐
相关产品推荐

