Reputation: 1457
I have some data in std::istream
and I need to save it to the disk. Here is my draft:
std::istream& i_stream = ReceiveBytes();
FILE* pFile;
pFile = fopen("C:\\my_file.exe", "wb");
char buffer[1024] = {0x0};
i_stream.read(buffer, 1024);
std::streamsize n = i_stream.gcount();
while (n > 0)
{
if (i_stream)
{
fwrite(buffer, sizeof(char), sizeof(buffer), pFile);
i_stream.read(buffer, 1024);
n = i_stream.gcount();
}
else n = 0;
}
fclose(pFile);
For some reason I don't save all the data from i_stream
, I lose about 50 bytes in the end of the i_stream
. What did I do wrong in the code? Is there any better solutions to save data from std::istream
to a file ?
Upvotes: 3
Views: 4914
Reputation: 1416
CRLF ("\r\n") input sequences, might be converted to simple LF ("\n"). There's a bug in the fwrite, the code attempts to write 1024 bytes, no matter what. There's no error checking on the output open, write or close.
More idiomatic is to have the input tests once in the while condition :
std::streamsize n;
i_stream.read(buffer, 1024);
while (i_stream || (n = istream.gcount()) != 0) {
fwrite(buffer, sizeof(char), n, pFile);
if (n) { i_stream.read(buffer, 1024) };
}
By mixing C++ streams and C stdio functions, the code's less consistent, than if it used streams for both read and write. An example of code to copy a binary file, using ifstream & ofstream is given at http://www.cplusplus.com/reference/ostream/ostream/write/ which might be helpful.
Upvotes: 4
Reputation: 153929
There are two possible issues. The first is that the
std::istream
you're using may not have been opened in binary
mode; you don't show us this. The second is that you're using
unformatted input. If you don't read the full 1024
bytes,
then the failbit
will be set in i_stream
. The test for
having read anything (even less than enough) bytes with
a formatted read is i_stream || istream.gcount() != 0
(or for
failure, !istream && istream.gcount() == 0
).
Upvotes: 2