C++ fstream << 和 >> 运算符与二进制数据的使用

12
我一直读到并听说,处理二进制文件时应该使用read()和write(),而不是<<和>>运算符,因为它们适用于格式化数据。我也读到过可以使用它们,但这是一个高级主题,我找不到任何人讨论这个问题。
最近我看到一些代码做了以下操作:
std :: ifstream file1(“x”,ios_base :: in | ios_base :: binary); std :: ofstream file2(“y”,ios_base :: app | ios_base :: binary);
file1 << file2.rdbuf();
当我指出在二进制文件中使用<<运算符时,有人告诉我rdbuf()调用返回streambuf *,<<重载streambuf*,并进行无格式的直接复制,因此是安全的。
这是真的,也是安全的吗?效率如何?有什么要注意的地方?详细信息将不胜感激。
谢谢!
3个回答

4

是的(请参见27.6.2.5.3/6,其中描述了流缓冲区的<<重载)。


3
那是标准里的一页吗? :) 如果有链接就更好了! - Skurmedel
这是对标准中某一段的引用。该标准本身并不公开。有些草案是可以获取的,但我手头没有链接。 - AProgrammer
好的,谢谢你澄清。他们应该将标准公开化。 - Skurmedel
1
他们靠出售它来赚钱,所以不太可能。但我同意这会很好。98版本的最新草案可以在ftp://ftp.research.att.com/pub/c++std/WP/CD2/获取。 - KTC
2
“他们”是谁?ISO和国家机构不是盈利组织。他们从销售标准所得的资金用于支付运营成本,事实上,流行的标准支持不太流行的标准。委员会成员及其雇主已经通过提供时间、支付会议旅费和住宿费、赞助会议以便提供房间等方式来支持这一过程,并且通常会支付会员费。这种安排并不是真正为PL设计的,但PL对于这些组织来说是一个相当特殊的领域,为他们做出例外是没有意义的。 - AProgrammer

3

这是一种完全安全且合理的复制流的方式。

请注意,它还允许这样的内容:

std::ifstream file_in1("x1", ios_base::in | ios_base::binary);
std::ifstream file_in2("x2", ios_base::in | ios_base::binary);
std::ofstream file_out("y", ios_base::app | ios_base::binary);

file_out << file_in1.rdbuf() << "\nand\n" << file_in2.rdbuf();

你有关于这个安全的详细信息吗?我知道你可以这样做,而且它似乎有效,但我的好奇心在于,参考文献中经常提到 << 和 >> 不适用于二进制数据。例如,这对于以二进制方式打开的文本文件和图像是否同样适用? - RC.
"<<和>>"是重载运算符,也就是说有很多实现方式。一般来说,它们用于文本,并会格式化第二个操作数。然而,streambuf的重载与所有其他重载基本不同。 - MSalters

1
在C++标准的§ 27.7.3.6.3中提到:
basic_ostream<charT,traits>& operator<< (basic_streambuf<charT,traits>* sb);
Effects: Behaves as an unformatted output function (as described in 27.7.3.7, paragraph 1).

§ 27.7.3.7描述了“未格式化输入”,基本上是二进制复制。这意味着“未格式化”的ostream函数对于二进制数据是安全的。我能找到的其他“未格式化”函数包括putwrite和(官方)flush

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