【发布时间】:2017-03-18 18:51:50
【问题描述】:
简介:
我正在阅读带有ReadFile 的文本文件。传递给ReadFile 的缓冲区使用cout 发送到标准输出。标准输出被重定向到一个文本文件。
问题:
虽然我的代码“有效”,但没有数据丢失,生成的文件比原始文件大。
在记事本中打开时,一切似乎都很好,但在Notepad++ 中打开时,我可以清楚地看到添加了额外的行。这些行是新行 (\n)。
复制此行为的MVCE在下方提交。
#include <iostream>
#include <Windows.h>
int main()
{
HANDLE hFile = ::CreateFile("C:\\123.txt",
GENERIC_READ,
FILE_SHARE_READ |
FILE_SHARE_WRITE |
FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
if (INVALID_HANDLE_VALUE == hFile)
return ::GetLastError();
char buffer[256];
DWORD bytesRead = 1, // dummy value so while loop can work
bytesWritten = 0; // needed for WriteFile, not for cout version
//======== so WriteFile outputs to console, not needed for cout version
HANDLE hStandardOutput = ::GetStdHandle(STD_OUTPUT_HANDLE);
if (INVALID_HANDLE_VALUE == hStandardOutput)
{
std::cout << "GetStdHandle error code = " << ::GetLastError() << std::endl;
::CloseHandle(hFile);
return ::GetLastError();
}
//============================
while(bytesRead)
{
// '\0' terminate buffer, needed for cout only
::memset(buffer, '\0', sizeof(buffer));
if (!::ReadFile(hFile,
buffer,
sizeof(buffer) - 1, // - 1 for '\0', not needed when using WriteFile
&bytesRead, NULL))
{
std::cout << "ReadFile error code = " << ::GetLastError() << std::endl;
break;
}
/*============= Works fine
if(!::WriteFile(hStandardOutput, buffer, bytesRead, &bytesWritten, NULL))
{
std::cout << "WriteFile error code = " << ::GetLastError() << std::endl;
break;
}*/
//------------- comment out when testing WriteFile
std::cout << buffer; // extra lines...
// std::cout.write(buffer, bytesRead); // extra lines as well...
//----------------------------------------
}
::CloseHandle(hFile);
return 0;
}
问题:
是什么导致了上述行为?如何解决?
我为解决问题所做的努力:
当我输入这篇文章时,我漫无目的地在谷歌上搜索,希望能找到一些线索。
我怀疑问题出在输出\n时,Windows似乎也插入了\r,但我不确定。
【问题讨论】:
-
这与文件完全无关。只有
std::cout <<的工作原理 -
@RbMm:你能解释一下,或者提供一个链接来解释为什么会发生这种情况吗?感谢您的评论(我没有忘记您的其他 IO 完成端口答案,我正在解决这个问题)。
-
cout不是为处理原始二进制数据而设计的。绝对正常,他可以添加额外的\r或\n字符。您将文件读取为原始二进制数据,但尝试写入格式化的字符串数据。结果不匹配也就不足为奇了。在这种情况下尝试使用 WriteFile 并进行比较。或确定你想要什么 -
cout不是为处理原始二进制数据而设计的 在 MVCE 中,我尝试使用cout.write,但也失败了……try use WriteFile是的,那工作,正如我已经在我的帖子中所说的那样。感谢您的回复。 -
新文件比原来大多少?我们是在说一些额外的字节吗?两倍大?这些类型的细节很重要。