从二进制模式的文件中读取块到缓冲区并将该缓冲区写入另一个文件

cod*_*odd 5 c++ ifstream ofstream

我想要实现这样的事情:

while (ifstream has not been entirely read)
{
   read a chunk of data into a buffer that has size BUFLEN
   write this buffer to ostream
}
Run Code Online (Sandbox Code Playgroud)

起初我试图通过使用ifstream.eof()我的条件来实现这一点,但我听说这不是要走的路.我一直在看std :: ios :: ifstream的其他功能,但无法弄清楚还有什么用.

PS:我正在使用缓冲区,因为正在传输的文件会变得非常大.

Jam*_*nze 7

iostream类负责所有必要的缓冲,因此您不必这样做.复制整个文件的通常习惯就是:

fout << fin.rdbuf();
Run Code Online (Sandbox Code Playgroud)

iostream负责所有必要的缓冲.(这是一种有点不寻常的用法<<,因为它没有格式化.历史原因,毫无疑问.)

如果你需要循环,也许是因为你想在重写数据之前对数据进行一些转换,那么它就是一个小问题,因为istream::read"失败"除非它读取所请求的字符数.因此,您还必须检查读取的字符数,并在读取失败时处理它们:

int readCount;
while ( fin.read( &buf[0], buf.size() )
        || (readCount = fin.gcount()) != 0 ) {
    //  ...
    fout.write( &buf[0], readCount );
}
Run Code Online (Sandbox Code Playgroud)

这相当丑陋; 一个更好的解决方案可能是将缓冲区包装在一个类中,并operator<<为此类定义一个.


Som*_*ude 6

该istream::read函数返回流,可以用作布尔表达式,因此您可以执行以下操作:

while (is.read(buffer, BUFLEN))
{
    outputfile.write(buffer, is.gcount());
}

if (is.eof())
{
    if (is.gcount() > 0)
    {
        // Still a few bytes left to write
        outputfile.write(buffer, is.gcount());
    }
}
else if (is.bad())
{
    // Error reading
}
Run Code Online (Sandbox Code Playgroud)

您可能想要检查循环内的写入是否也不会失败.