2010-09-27 140 views
0

是什么Wrtiting字符串内存流 - 指向字符串的指针

这之间的区别:

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. 我真的必须使用指针(SourceString)^或SourceString [1]也可以吗?
  2. 代码(他们两个)将与德尔福2010年(unicode)?

回答

2

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

2:此代码将而不是使用Unicode。你必须乘以它:xxx * sizeof(Char)。 (这将适用于德尔福的Unicode版本之前和之后的版本。)但是,除非大量使用非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我写的,让人们更方便读取和写入各种事情,并从流的一部分,但如果你不喜欢类帮手,它不应该是太难的基本思路适应不同的格式)

+0

“这是TStream的类助手的一部分” - 我的代码也来自我自己的类助手:)虽然我很确定它不会与Delphi 2010一起工作,除非将字符串更改为AnsiString(我刚刚做过)。尽管如此,我并不是真的对保存UNICOE感兴趣,我承认我会更新我的代码(使用你的)来支持UNICODE。谢谢。 – Ampere 2010-09-27 22:24:26

+0

SourceString [1]版本更具可读性 - 感谢Mason的确认。我在Borland的网站上找到了这些代码,我认为“如果他们以此为例,它肯定是一些东西。”做它更复杂的是什么? – Ampere 2010-09-27 22:30:07

+5

当你有范围检查启用(你应该总是启用范围检查),那么当SourceString [1]'长度为零时会引发一个异常,而'Pointer(SourceString)'将是一个空指针,因为你传入的字节数也是零,所以不会被取消引用。请参阅*清单4 * [我的网站](http://www.cs.wisc.edu/~rkennedy/string-stream)。 – 2010-09-27 22:39:46

2

在生成的汇编代码:

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

所以指针(ASTRING)^要使用,如果你即将读取数据,而不是对其进行修改。

And aString [1]用于在被调用函数中修改aString的情况。

在实践中,我使用指针(aString)^它可以产生更高效的代码。

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

附加说明:如果ASTRING是 '',指针(ASTRING)将返回

+0

换句话说,指针(aString)^更快,而aString [1]更安全? – Ampere 2010-09-28 19:06:21

+0

你可以这么说:)但在某些情况下,对UniqueString的隐式调用是强制性的以避免内存损坏:在使用指针(aString)之前,您可以使用明确的UniqueString调用^如果您希望代码既安全又快速 – 2010-09-29 11:31:26