如何将字符串转换为字节数组并反向操作

14

我必须将字符串写入一个二进制MIDI文件中。标准要求必须知道字符串的字节数。由于我还想编写移动设备版本,所以不能使用AnsiString,这是确保字符串为单字节字符串的好方法。这样可以简化事情。我测试了以下代码:

TByte = array of Byte;

function TForm3.convertSB (arg: string): TByte;
var
   i: Int32;
begin
   Label1.Text := (SizeOf (Char));
   for i := Low (arg) to High (arg) do
   begin
      label1.Text := label1.Text + ' ' + IntToStr (Ord (arg [i]));
   end;
end; // convert SB //

convertSB ('MThd');
它在Windows和Android中返回2 77 84 104 100(作为标签文本)。这是否意味着Delphi默认将字符串视为UTF-8?这将极大地简化事情,但我在帮助文档中找不到它。将其转换为字节数组的最佳方法是什么?读取每个字符并测试它是1、2还是4个字节,并在数组中分配此空间吗?要将其转换回字符:只需读取字节数组,直到遇到一个小于128的字节即可。

1
@Tlama - 这是故意的 :-) 当编写MIDI文件时,我可以组织它成这种情况。我想知道当使用仅UTF-8字符时Delphi在做什么,它是否会自动将其更改为两个字节的表示形式?它不会,并且有趣的是,它对Windows和Android保持一致。 - Arnold
实际上,你问题中代码中的字符确实是两个字节宽度。这就是 SizeOf 调用告诉你的。 - David Heffernan
1个回答

51

Delphi中的字符串在内部被编码为UTF-16。事实上SizeOf(Char)为2已经是一个很大的提示了。

你所有字符都具有ASCII范围内的序数,这是因为UTF-16扩展了ASCII,即0到127范围内的字符在UTF-16中具有相同的序数值。而且你的所有字符都是ASCII字符。

尽管如此,你无需担心内部存储。只需要使用TEncoding类在字符串和字节数组之间进行转换。例如,要转换为UTF-8,可以这样写:

bytes := TEncoding.UTF8.GetBytes(str);

而在相反的方向:

str := TEncoding.UTF8.GetString(bytes);

该类支持许多其他编码方式,如文档中所述。从问题中没有明确指出需要使用哪种编码方式。希望您可以从这里解决其余的问题。


正是我所需要的。谢谢! - Arnold
2
我想要仅使用UTF-8读写文件,这一点你已经猜到了。TEncoding是一个很棒的类,可以解决我很多字符串格式问题。我的问题源于我担心必须自己处理所有编码,因此才会问关于内部表示的问题。 - Arnold

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