从std::istream保存数据到文件的最佳方法

3

我有一些数据在std::istream中,需要保存到磁盘上。这是我的草稿:

    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);

由于某种原因,我没有保存从i_stream读取的所有数据,我在i_stream末尾丢失了约50个字节。在代码中哪里出错了?有没有更好的方法来将std::istream中的数据保存到文件中?


1
可能是因为最后一次调用i_stream.read()之后,if (i_stream)失败了,所以最后的fwrite没有被调用。 - 001
1
此外,在 fwrite 中,您应该写入 n 个字节,而不是 sizeof(buffer) 个字节。 - 001
2个回答

4

CRLF ("\r\n") 输入序列可能会被转换为简单的 LF ("\n")。

fwrite 中存在一个 bug,代码尝试写入 1024 字节,不管什么情况。

输出打开、写入或关闭没有错误检查。

更加惯用的做法是在 while 条件中仅测试输入一次:

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) };
}

通过混合使用C++流和C标准I/O函数,代码的一致性较差,如果使用流进行读写,则更加一致。可以参考http://www.cplusplus.com/reference/ostream/ostream/write/中给出的使用ifstream和ofstream复制二进制文件的示例。


2
有两个可能的问题。第一个是您使用的std :: istream 可能没有以二进制模式打开; 您没有向我们展示这一点。第二个问题是您在使用未格式化的输入。如果您没有读取完整的1024字节,则i_stream 中将设置failbit 。使用格式化读取时,对于已读取任何内容(甚至不足够的)的测试为i_stream || istream.gcount()!= 0 (或出现故障时, !istream&& istream.gcount() == 0 )。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接