如何使用AnsiString存储二进制数据?

时间:2014-09-22 22:48:38

标签: c++builder binary-data ansistring

我有一个简单的问题。

我想使用AnsiString作为二进制数据的容器。我主要从TMemoryStream或TFileStream加载这些数据,经过一些处理后我将它从AnsiString中保存回来。工作正常,没有发现问题。

但是,从我所看到的使用它开始,就像使用Sysutils::TBytes的争论一样。为什么? Sysutils::TBytes使用的有用方法少得多,我可以使用它来操纵存储在内部的数据,例如AnsiString。与AnsiString相比,它显然是半成品容器。

我应该关注转换为常规字符串的唯一问题还是还有其他原因我为什么要真正使用不足以TBytes呢?我没有将AnsiString转换为其他字符串类型 - 这就是其他地方引用的可能问题。

我如何加载数据的示例:

AnsiString data;
boost::scoped_ptr<TFileStream> fs(new TFileStream(FileName, fmOpenRead | fmShareDenyWrite));
data.SetLength(fs->Size);
fs->Read(data.c_str(), fs->Size);

我如何保存数据的示例:

// fs wants void * so I have to use data.data() instead of data.c_str() here
fs->Write(data.data(), data.Length());

那么存储二进制数据应该是否安全?

1 个答案:

答案 0 :(得分:4)

  

我想使用AnsiString作为二进制数据的容器。

一个字 - DON&#39; T !有一天它会咬你。使用更合适的容器,例如TBytesTMemoryStreamstd::vector<byte>等。

  

工作正常,没有发现问题。

认为自己很幸运。从C ++ Builder 2009开始,AnsiString具有代码页感知功能,如果您在传递AnsiString时并不十分谨慎,它将导致数据转换。迟早,你可能会滑倒,它可能会破坏你的二进制数据。

  

但是从我所看到的使用Suputils :: TBytes这样的争论开始。为什么呢?

因为它是一个实际的原始二进制容器,专门用于原始字节。

  

Sysutils :: TBytes的有用方法少得多,我可以用它来操作存储在里面的数据,例如AnsiString。

您不应该将二进制数据作为文本开始操作。而且由于你使用的是Boost和STL之类的东西,你应该考虑使用它们的二进制容器。他们有更多的功能。

话虽这么说,XE7确实引入了一些新的函数来操作Delphi风格的动态数组(如TBytes),包括插入,删除和连接:

String-Like Operations Supported on Dynamic Arrays

虽然这些新功能看起来不像是C ++ Builder的DynamicArray类(TBytestypedef)。

  

与AnsiString相比,它显然是半成品容器。

AnsiString文字字符的容器。期。始终如此,永远如此。人们通过利用sizeof(char)==sizeof(byte)的事实来滥用它。这达到了一定程度,但近年来继续滥用它已经变得很危险。

  

我应该关注转换为常规字符串的唯一问题还是还有其他原因我为什么要真正使用不足够的TBytes呢?

那,以及Embarcadero自2009年以来逐步淘汰AnsiString这一事实。在移动编译器中禁用8位字符串,桌面编译器也只是时间问题。

为什么要将原始字节作为字符串开始操作?您能举例说明AnsiString使用TBytes无法做到的事情吗?

  

那么存储二进制数据应该是否安全?

在您的具体示例中,是(是的,您可以在调用c_str()时使用data()代替fs->Write()