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

C++ 将数据从std::istream保存到文件的最佳方法,c++,windows,file,stream,C++,Windows,File,Stream,我在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.gc

我在
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_流
中的所有数据,我在
I_流
的末尾丢失了大约50个字节。我在代码中做错了什么?是否有更好的解决方案将数据从
std::istream
保存到文件?

可能存在两个问题。首先是
std::istream
您正在使用的文件可能未以二进制文件打开 模式你不给我们看这个。第二,你正在使用 未格式化输入。如果未读取完整的
1024
字节, 然后将在
i\u流中设置
failbit
。测试 已经用 格式化读取是
i|u流| istream.gcount()!=0
(或用于
失败,
!istream&&istream.gcount()==0

有两个可能的问题。首先是
std::istream
您正在使用的文件可能未以二进制文件打开 模式你不给我们看这个。第二,你正在使用 未格式化输入。如果未读取完整的
1024
字节, 然后将在
i\u流中设置
failbit
。测试 已经用 格式化读取是
i|u流| istream.gcount()!=0
(或用于 失败,
!istream&&istream.gcount()==0

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 STDIO函数,代码比读和写流使用时的一致性要差。使用ifstream&ofstream复制二进制文件的代码示例可能会有所帮助。

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 STDIO函数,代码比读和写流使用时的一致性要差。使用ifstream和ofstream复制二进制文件的代码示例可能会有所帮助。

如果(i\u stream)
在最后一次调用
i\u stream.read()
后失败,那么最终的
fwrite
不会被调用。另外,在
fwrite
中,您应该写入
n
字节,而不是
sizeof(buffer)
bytes。如果在最后一次调用
i\u stream.read()
后(i\u stream)
失败,则可能
if(i\u stream)
失败,因此最终的
fwrite
不会被调用。此外,在
fwrite
中,您应该写入
n
字节,而不是
sizeof(buffer)
字节。