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

时间:2011-11-25 13:16:20

标签: 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
}

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

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

3 个答案:

答案 0 :(得分:7)

iostream课程负责所有必要的缓冲,所以你不需要 不得不。复制整个文件的通常习惯就是:

fout << fin.rdbuf();

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

如果你需要循环,也许是因为你想做一些 在重写之前对数据进行转换,然后就是一点点 tricker,因为istream::read“失败”,除非它读取 请求的字符数。因此,您还必须检查 读取了多少个字符,即使读取失败也会处理它们:

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

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

答案 1 :(得分: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
}

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

答案 2 :(得分:0)

你的逻辑完全错了。

你需要更像这样:

while (a chunk larger than zero could be read)
{
  write chunk to output
}

看看它是如何更简单?没有必要明确检查“文件结束”,只需读取数据直到失败。然后你就完成了。