如何使用Delphi将字节数组转换为字符串?

如何使用Delphi将字节数组转换为字符串?,delphi,delphi-7,Delphi,Delphi 7,我正在用Delphi开发一个项目,我想把字节数组转换成字符串类型。我该怎么办 示例C#代码: 专用无效ListenerOnDataTransmit(DataTransmitEventArgs e) { TransmittedMg=位转换器.ToString(例如TransmittedBytes,0,例如TransmittedBytes.Length); 请尝试{Invoke(new EventHandler(updateTransmistedMessageListView));} 捕获{} }

我正在用Delphi开发一个项目,我想把字节数组转换成字符串类型。我该怎么办

示例C#代码:

专用无效ListenerOnDataTransmit(DataTransmitEventArgs e)
{
TransmittedMg=位转换器.ToString(例如TransmittedBytes,0,例如TransmittedBytes.Length);
请尝试{Invoke(new EventHandler(updateTransmistedMessageListView));}
捕获{}
}
该方法“将指定字节数组中每个元素的数值转换为其等效的十六进制字符串表示形式”。您可以在Delphi 7中使用循环中的
SysUtils.IntToHex()
函数手动执行相同的操作,例如:

使用
…,SysUtils;
变量
字节:字节数组;
s:字符串;
i:整数;
开始
字节:=。。。;
s:='';
如果字节为零,则
开始
s:=IntToHex(字节[0],2);
对于i:=1到高(字节)do
s:=s+'-'+IntToHex(字节[i],2);
结束;
结束;

我怀疑您想要一个函数,它接受字节数组(或指向字节的原始指针),并返回包含十六进制格式数据的字符串

我总是使用我的以下例行程序来执行此操作:

函数BytesToString(ABuf:PByte;ALen:Cardinal):字符串;超载;
常数
十六位数:字符的数组[0..$F]='0123456789ABCDEF';
变量
i:整数;
开始
如果ALen=0,则
开始
结果:='';
出口
结束;
设置长度(结果,3*ALen-1);
结果[1]:=六位数[ABuf^shr 4];
结果[2]:=六位数[ABuf^和$0F];
对于i:=1到ALen-1 do
开始
公司(阿布夫);
结果[3*i+0]:='';
结果[3*i+1]:=六位数[ABuf^shr 4];
结果[3*i+2]:=六位数[ABuf^和$0F];
结束;
结束;
类型
TByteArray=字节数组;
函数BytesToString(ABytes:TByteArray):字符串;超载;
开始
结果:=BytesToString(pbytes,ABytes),Length(ABytes));
结束;
第一个重载采用原始指针和长度,而第二个重载采用动态字节数组

这是一个非常快速的实现,因为我不使用字符串连接(这需要常量堆重新分配)


上面的代码是专门为旧的Delphi7编译器和RTL编写的。现代版本看起来更像这样:

函数BytesToString(ABuf:PByte;ALen:Cardinal):字符串;超载;
常数
十六位数:字符的数组[0..$F]='0123456789ABCDEF';
变量
i:整数;
开始
如果ALen=0,则
退出(“”);
设置长度(结果,3*ALen-1);
结果[1]:=六位数[ABuf[0]shr 4];
结果[2]:=六位数[ABuf[0]和$0F];
对于i:=1到ALen-1 do
开始
结果[3*i+0]:='';
结果[3*i+1]:=六位数[ABuf[i]shr 4];
结果[3*i+2]:=六位数[ABuf[i]和$0F];
结束;
结束;
函数BytesToString(ABytes:TArray):字符串;超载;
开始
结果:=BytesToString(pbytes,ABytes),Length(ABytes));
结束;


上述代码使用空格字符对每个字节进行分组。当然,您可能不希望这样做,但不分组是一项更简单的任务,因此我将把它留作练习。

您忘了告诉我们“将字节数组转换为字符串”是什么意思。有几种不同的解释,都是合理的:(1)将字节数组视为ASCII,并获取它编码的文本;(2) 将字节数组视为UTF8,并获取其编码的文本;(3) 获取数组的原始十六进制数据表示形式;(4) 获取阵列的原始二进制数据表示形式;等等。在后一种情况下,您想对数字进行分组吗?完全有效,但由于字符串的不断重新分配,对于长缓冲区来说(非常)低效。@AndreasRejbrand是的,有许多不同的方法来实现这一点。以上只是一个例子。对于小缓冲区来说,它当然足够好了,所以+1。至少现在我们有了一个非常好的问答,我们可以作为一个标准问答来关闭重复项。@RemyLebeau谢谢,我一直在寻找这个。老实说,当我看到
3*ALen
。。。也就是说,在我看到space.IIRC之前,Delphi7中没有基于PByte的ptr数学,所以我用一些更古老的方法代替了它。