ostream::write实际写入了多少字节?

12
假设我向ostream::write发送一个大缓冲区,但只有其开头部分成功写入,其余部分未被写入。
int main()
{
   std::vector<char> buf(64 * 1000 * 1000, 'a'); // 64 mbytes of data
   std::ofstream file("out.txt");
   file.write(&buf[0], buf.size()); // try to write 64 mbytes
   if(file.bad()) {
     // but suppose only 10 megabyte were available on disk
     // how many were actually written to file???
   }
   return 0;
}

哪个ostream函数可以告诉我实际写入了多少字节?


与您的问题无关:不得使用 void main(),并且您将参数顺序放反了,应为vector::vector() - Robᵩ
感谢 @Robᵩ 修正代码并集中精力回答问题。 - Aviad Rozenhek
2个回答

13

您可以使用.tellp()来获取流中的输出位置,以计算写入的字节数:

size_t before = file.tellp(); //current pos

if(file.write(&buf[0], buf.size())) //enter the if-block if write fails.
{
  //compute the difference
  size_t numberOfBytesWritten = file.tellp() - before;
}

请注意,没有任何保证numberOfBytesWritten确实是写入文件的字节数,但对于大多数情况,这应该是有效的,因为我们没有任何可靠的方法来获取实际写入文件的字节数。


如果ostream写入套接字而不是文件,@AProgrammer的答案仍然有效吗? - Aviad Rozenhek
@AviadRozenhek:即使你将数据写入文件,它也不是可靠的。但在C++中,.tellp()就是我们所能得到的。 - Nawaz
@Nawaz,问题是[我认为]对于许多将ostream作为套接字包装器的实现,tellp()总是返回-1 ... - Aviad Rozenhek
@Nawaz 使用 flush() 有帮助吗? - Aviad Rozenhek
10
如果write操作失败,流上的所有后续操作都将不起作用,直到错误被清除为止。其中包括必须返回-1的tellp操作,如果之前有任何操作失败。 - James Kanze
显示剩余3条评论

2

我没有看到与 gcount() 相等的函数。直接使用 sputn() 写入 streambuf 可以给你一个指示,但是你的请求存在一个根本性问题:写入是有缓冲区的,故障检测可能会延迟到实际写入(刷新或关闭),并且没有办法访问操作系统真正写入的内容。


事实上,唯一的解决方案是在写入之前找出文件的大小(从系统中,使用特定于系统的调用),然后在写入之后关闭文件并使用相同的系统特定调用来查找新的大小。 - James Kanze

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