当我试图找到this question的答案时,我写了这个小测试程序:
#include <iostream>
#include <fstream>
#include <vector>
#include <iterator>
#include <algorithm>
void writeFile() {
int data[] = {0,1,2,3,4,5,6,7,8,9,1000};
std::basic_ofstream<int> file("test.data", std::ios::binary);
std::copy(data, data+11, std::ostreambuf_iterator<int>(file));
}
void readFile() {
std::basic_ifstream<int> file("test.data", std::ios::binary);
std::vector<int> data(std::istreambuf_iterator<int>(file),
(std::istreambuf_iterator<int>()));
std::copy(data.begin(), data.end(),
std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
}
int main()
{
writeFile();
readFile();
return 0;
}
它按预期工作,将数据写入文件,并在读取文件后正确打印:
0 1 2 3 4 5 6 7 8 9 1000
但是,我不确定是否存在任何陷阱(除了字节问题,在处理二进制数据时总会有这些问题)?这是允许的吗?
答案 0 :(得分:4)
它按预期工作。
我不确定你在期待什么...
这是允许的吗?
这可能不便携。 Streams依赖于char_traits
以及仅在char
和wchar_t
标准中定义的方面。一个实现可以提供更多,但我的赌注是你依赖于这些模板的最小默认实现而不是int
的有意识实现。如果更深入的使用会导致问题,我不会感到惊讶。
答案 1 :(得分:2)
在任何事物上实例化任何iostream类或basic_string 但是char或wchar_t,没有提供特定的自定义特征类, 是未定义的行为;我见过的大多数库都定义了它 做某事,但这个定义通常没有指定,而且是 VC ++和g ++之间存在差异(我看过两个案例)。如果你 定义和使用自己的traits类,一些功能应该 工作
几乎所有格式化的插入器和提取器(<<
和
>>
运营商),istream
和ostream
委托各个方面
现场;如果使用其中任何一个,你将不得不采取措施
确保这些工作也是如此。 (这通常意味着提供一个新的
numpunct facet。)
即使您只使用streambuf
(如您的示例所示),filebuf
使用codecvt方面。并且不需要提供实现
一个codecvt,如果确实如此,它可以做任何它想要的东西
它。因为filebuf
总是在{和} {1}}之间写入和读取char
文件,这个翻译必须做点什么。我其实很喜欢
因为这个原因,你的代码很有用。但你还是没有
知道磁盘上实际是什么,这意味着你无法记录它,
这意味着将来某个时候你将无法阅读它。
如果您的目标是编写二进制数据,那么您的第一步应该是
定义二进制格式,然后写入读写函数
实现它。可能使用iostream&lt;&lt;和&gt;&gt;语法,和
可能使用basic_streambuf<char>
作为实际输入和
输出;一个basic_streambuf<char>
,你已经仔细地了解了
“C”语言环境。或者不是定义自己的二进制格式,只需使用
现有的,如XDR。 (所有这一段都假设你想要
保存数据,稍后再读。如果这些只是临时文件,
用于在单次运行期间将临时内部数据溢出到磁盘,以及
将在程序执行结束时删除,更简单的解决方案
是有效的。)