WinAPI ReadFile returns 损坏的数据
WinAPI ReadFile returns corrupted data
我正在我的 Visual C++ 项目中编写一个函数,该函数通过 WinAPI 以 2000 字节为增量读取文件内容,returns 将其作为 std::string。
当文件远大于缓冲区(例如 100 KB)时出现问题,我在有效数据中间的文件中的多个位置添加了垃圾。这是一个很长的 0xcccccccc...
序列,由 3-4 个其他字节终止,通常出现在单词的中间。该函数不会失败,否则 none 的有效数据丢失。
我没有检查确切的位置,但似乎这发生在缓冲区大小增量(或缓冲区大小增量的倍数)时。如果我将缓冲区的大小增加到超过测试文件的大小,问题就会消失。是什么原因导致这种情况发生?我做错了什么?
std::string read_file(std::string filename) {
HANDLE hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
std::string errortext("Error opening " + filename + ", bad handle value: " + to_string((int)hFile));
MessageBox(hwnd, errortext.c_str(), "Error", 0);
return "";
}
char buffer[2000] = "";
std::string entire_file = "";
DWORD dwBytesRead = 0;
while (ReadFile(hFile, buffer, sizeof(buffer), &dwBytesRead, NULL))
{
if (!dwBytesRead)
break;
entire_file += buffer;
}
CloseHandle(hFile);
return entire_file;
}
entire_file += buffer;
假设 buffer 是一个以 nul 结尾的字符串,在你的例子中,它不是。
试试这个
entire_file.append(buffer, dwBytesRead);
这是一个很好的代码示例,应该敲响警钟,因为您没有使用 dwBytesRead
变量(除了终止循环)。
我正在我的 Visual C++ 项目中编写一个函数,该函数通过 WinAPI 以 2000 字节为增量读取文件内容,returns 将其作为 std::string。
当文件远大于缓冲区(例如 100 KB)时出现问题,我在有效数据中间的文件中的多个位置添加了垃圾。这是一个很长的 0xcccccccc...
序列,由 3-4 个其他字节终止,通常出现在单词的中间。该函数不会失败,否则 none 的有效数据丢失。
我没有检查确切的位置,但似乎这发生在缓冲区大小增量(或缓冲区大小增量的倍数)时。如果我将缓冲区的大小增加到超过测试文件的大小,问题就会消失。是什么原因导致这种情况发生?我做错了什么?
std::string read_file(std::string filename) {
HANDLE hFile = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, NULL, NULL);
if (hFile == INVALID_HANDLE_VALUE)
{
std::string errortext("Error opening " + filename + ", bad handle value: " + to_string((int)hFile));
MessageBox(hwnd, errortext.c_str(), "Error", 0);
return "";
}
char buffer[2000] = "";
std::string entire_file = "";
DWORD dwBytesRead = 0;
while (ReadFile(hFile, buffer, sizeof(buffer), &dwBytesRead, NULL))
{
if (!dwBytesRead)
break;
entire_file += buffer;
}
CloseHandle(hFile);
return entire_file;
}
entire_file += buffer;
假设 buffer 是一个以 nul 结尾的字符串,在你的例子中,它不是。
试试这个
entire_file.append(buffer, dwBytesRead);
这是一个很好的代码示例,应该敲响警钟,因为您没有使用 dwBytesRead
变量(除了终止循环)。