1

我有一个简单的问题。

我想使用 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());

那么正确存储二进制数据应该是安全的吗?

4

1 回答 1

4

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

一个字——不要!总有一天它会咬你。使用更合适的容器,例如TBytes, TMemoryStream,std::vector<byte>等。

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

认为自己很幸运。从 C++Builder 2009 开始,AnsiString它是代码页感知的,如果你在传递时不是很小心,它会导致数据转换AnsiString。迟早,您可能会犯错,并且有可能损坏您的二进制数据。

但从我所看到的使用它的情况来看,使用 Sysutils::TBytes 的争论不休。为什么?

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

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

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

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

动态数组支持的类字符串操作

不过,看起来那些新函数并没有进入 C++Builder 的DynamicArray类(TBytes属于typedef)。

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

AnsiString文本字符的容器。时期。一直是,永远都是。人们利用sizeof(char)==sizeof(byte). 这在一定程度上起到了作用,但近年来继续滥用它变得很危险。

是我应该关心转换为常规字符串的唯一问题,还是有其他原因为什么我应该真正使用不足的 TBytes 来代替?

这一点,以及 EmbarcaderoAnsiString自 2009 年以来一直在逐步淘汰的事实。移动编译器中禁用了 8 位字符串,桌面编译器效仿只是时间问题。

你为什么想将原始字节作为字符串操作?你能举个例子说明你可以做而AnsiString你不能做的事情TBytes吗?

那么正确存储二进制数据应该是安全的吗?

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

于 2014-09-23T01:38:36.367 回答