Delphi:如何从TBytes读取X位?

时间:2016-03-25 08:55:16

标签: delphi bit-manipulation byte bytearray

我遇到了从TBytes读取随机位数的问题。首先,我遵循了这个问题的建议(关于使用ubitstream.pas单元的答案):Handling arbitrary bit length data in Delphi? 我的例子: binaryfeed(TBytes)=(255,0,0,0,0,0,11,1,112,128,128,130,81);

  1. 我读了8位并得到255 - 好的。职位是8。
  2. 我读了另外24位并得到0 - 确定。职位是32。
  3. 我读了另外24位,得到393216而不是6.位置是56。
  4. 393216是0000 0000 0000 0110 0000 0000 0000 0000

    我可以理解它为什么会发生,但我无法弄清楚如何截断这些额外的零位。有任何想法吗?

2 个答案:

答案 0 :(得分:7)

问题是endianness

00000110 00000000 00000000

是393216.反转三个字节,你有

00000000 00000000 00000110 

这是6。

您使用的代码是小端,但您希望大端的行为。您需要更改代码以解决这种不匹配问题。

从我们在问题中看到的,你总是阅读整个字节,因此不需要你使用的代码的复杂性。您可以在字节级别操作。显然你仍然需要正确地考虑字节顺序,但这不是很具挑战性。

答案 1 :(得分:0)

首先想到你的容器。如果将字节读入32位整数,则应使用shr / shl将​​位移动到位。 将你不想要的最左边的位置移出32位范围并不常见,然后将剩余的X位置缩小以获得字节值(或字,或任何你需要的大小)。

var
  value: integer;
begin
  value := (Readint32FromBuffer shl 8) shr 8;
  writeln(value.tostring);
end;

在上面的代码中,我们不希望包含前8位,所以我们将整个8位向左移,然后向后移8位。当它们移动并离开边缘时,这会将这些位清零。容器。

使用SHL和SHR在变量内部移动位/字节。但请记住容器的大小。字(16位),整数(32位)等。

您也可以使用AND和OR掩码来实现一些相同的功能,尽管SHL和SHR通常对于与CPU寄存器(32位或64位)大小相同的变量更快。