将字符串写入TMemoryStream - 指向字符串的指针

时间:2010-09-27 21:37:43

标签: delphi

之间有什么区别

这样:

SourceString := 'I am doing just fine!';     
MemoryStream.ReadBuffer(Pointer(SourceString)^, xxx);

(此处提供完整源代码:http://edn.embarcadero.com/article/26416

和这段代码(我的):

SetLength(SourceString, xxx);
MemoryStream.ReadBuffer(SourceString[1], xxx);  
  1. 我真的必须使用Pointer(SourceString)^或SourceString [1]也可以吗?
  2. 代码(两者都适用)将与Delphi 2010(unicode)一起使用?

2 个答案:

答案 0 :(得分:2)

1:SourceString[1]版本更具可读性。当他们不是完全必要的时候我不喜欢使用指针。

2:此代码将与Unicode一起使用。你必须乘以它:xxx * sizeof(Char)。 (这将适用于Unicode前后版本的Delphi。)但除非你大量使用非Ansi字符,否则这将浪费大量空间。我更喜欢做的是:

procedure TStreamEx.WriteString(const data: string);
var
  len: cardinal;
  oString: UTF8String;
begin
  oString := UTF8String(data);
  len := length(oString);
  self.WriteBuffer(len, 4);
  if len > 0 then
    self.WriteBuffer(oString[1], len);
end;

procedure TStreamEx.ReadString(const data: string);
var
  len: cardinal;
  iString: UTF8String;
begin
  self.ReadBuffer(len, 4);
  if len > 0 then
  begin
    SetLength(iString, len);
    self.ReadBuffer(iString[1], len);
    result := string(iString);
  end
  else result := '';
end;

(这是我写的class helper for TStream的一部分,这使得从流中读取和写入各种内容变得容易得多。但如果你不喜欢上课助手,那就不应该太难了使基本思想适应不同的格式。)

答案 1 :(得分:2)

在生成的asm代码中:

  • 指针(aString)^ 会将字符串地址直接传递给过程/函数/方法;
  • aString [1] 会调用 UniqueString ,然后将字符串地址传递给过程/函数/方法。

因此,如果您要读取数据而不是修改数据,则使用指针(aString)^

如果您要修改被调用函数中的aString,则使用 aString [1]

实际上,我使用指针(aString)^ 来生成更高效的代码。

请注意,这个隐式 UniqueString 并不是那么慢:如果字符串的当前引用计数为1(这意味着只有一部分代码使用字符串,这很可能),它立即返回。但是在用于检查引用计数值的 UniqueString 中有一个LOCK asm前缀,并且使用此LOCK asm不是多线程友好的。这就是为什么我在编码时尽量避免使用 aString [1]

附加说明:如果 aString 为'',指针(aString)将返回 nil