如何将TBytes转换为RawByteString?

6
在Delphi 2009中,将声明为TBytes的字节数组转换为RawByteString的最佳方法是什么?此代码实际上有效,也许有一种更快的方法(不使用循环):
   function Convert(Bytes: TBytes): RawByteString; 
   var
     I: Integer;
   begin
     SetLength(Result, Length(Bytes));
     for I := 0 to ABytes - 1 do
       Result[I + 1] := AnsiChar(Bytes[I]);
   end;
4个回答

16

最佳方法是这样的:

function Convert(const Bytes: TBytes): RawByteString; inline;
begin
  SetString(Result, PAnsiChar(pointer(Bytes)), length(Bytes));
end;

不要忘记对字节参数使用 const 来生成更快的代码。


7
您可以考虑使用move(未经测试)
function Convert(const Bytes: TBytes): RawByteString; 
begin
  SetLength(Result, Length(Bytes));
  Move(Bytes[0], Result[1], Length(Bytes))  
end;

使用"const"来定义参数,这样数组就不会被复制两次。


1
SetLength() 会调用 ReallocMem 来重新调整现有的 RawByteString,因此如果您在循环中调用此函数,则此版本可能会不必要地 move() 先前的数据。使用 SetString(Result, PAnsiChar(Bytes), length(Bytes)) 可以更快速地完成操作。 - Arnaud Bouchez

7
将字节转换为RawByteString的最简单方法是使用SetString()
此外,为了避免数据丢失,如果RawByteString被分配给其他字符串类型,应将代码页赋给RawByteString,以便其字符数据正确地转换为接收字符串的字符集:
function Convert(const Bytes: TBytes): RawByteString; 
begin
  SetString(Result, PAnsiChar(PByte(Bytes))^, Length(Bytes));
  SetCodePage(Result, ..., False);
end;

我认为使用RawByteString的重点在于它不像AnsiStringUtf8String等类型那样缺乏代码页信息。 - blerontin
3
@blerontin RawByteString编译时缺少字符集,但它继承了被赋值的字符串的运行时字符集。即使字节载荷本身没有携带字符集,字节数组也有一个隐含的字符集。正如我在答案中所说,RawByteString 可以被赋值给其他字符串类型,因此它需要在其载荷中携带有效的字符集,以便促进正确的赋值,避免数据丢失。 - Remy Lebeau

5

请记得进行测试:

如果长度(以字节为单位)大于0,则移动......


这应该是对第一个(已接受的)答案的评论,我猜。 - blerontin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接