考虑下面的代码片段,它获取一些二进制数据并将其写入ostringstream
对象:
unsigned char* payload;
unsigned long size;
GetData(&payload, &size);
std::cout << md5(payload, size) << std::endl;
std::ostringstream stream;
stream.write((const char*)payload, size);
std::cout << md5(payload, size) << std::endl;
问题是,两个打印的哈希值彼此不同,这意味着payload
已经改变了。我试着用std::ostringstream stream(std::ios::out | std::ios::binary)
在二进制模式下打开stream
,它没有什么不同,我没有预料到它会,无论如何。
另一个事实是,每次重新运行程序时,我都会从第二个print语句获得不同的校验和。第一个哈希值总是相同的
现在,我如何将二进制数据正确地写入ostringstream?问题是否可以转换为const char*
(GetData
方法将unsigned char**
作为第一个参数)?
更新:根据评论,这里有一些更多的解释:
- 比较原始数据和写入数据的二进制差异,我看到写入数据在某些地方向右移动(24字节)。它还在最开始添加了一些字节。我还是觉得这和演员阵容有关。
-
GetData
和实际写入之间没有更多的代码。 - GetData工作正确,因为调用后的校验和是正确的(我知道校验和应该是什么)。 我不能发布可编译的代码,因为
- 系统详细信息为:gcc版本4.6.3在Ubuntu 12.04 64位
GetData
。这是没有必要的,我已经将问题隔离到调用write
的行。问题的奥秘原来在于数据的大小。
在实验了不同的大小值后,发现ostringstream
的内部缓冲区大约是65KB,确切地说是65504字节。当大小较大时,会出现奇怪的移位和残缺的字节。
stream.rdbuf()->pubsetbuf((const char*)payload, payloadSize)
代替write
方法。但是当这个作用域终止时,有效载荷将失效,stream
不能再在其他任何地方使用。在我的例子中,它需要在其他地方使用。
这表明:
- 我确实是对的,问题是与
ostringstream
,但不是与哈希或其他任何东西。 STL的字符串流显然有默认的缓冲区大小限制。这是将来要记住的。