5

我正在尝试实现这样的目标:

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()我的 while 条件来实现这一点,但我听说这不是要走的路。我一直在研究 std::ios::ifstream 的其他功能,但不知道还能使用什么。

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

4

3 回答 3

7

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

fout << fin.rdbuf();

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

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

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

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

于 2011-11-25T13:32:28.697 回答
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
}

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

于 2011-11-25T13:20:58.040 回答
0

你的逻辑是完全错误的。

你需要更像这样:

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

看看这更简单吗?无需显式检查“文件结尾”,只需读取数据直到失败。然后你就完成了。

于 2011-11-25T13:18:10.010 回答