Dart TypedData 和大/小端表示

问题描述

如果我运行以下代码

Uint8List bytes = Uint8List.fromList([1,128]);
ByteBuffer byteBuffer = bytes.buffer;
Uint16List sixteenBitList = byteBuffer.asUint16List();
print(sixteenBitList);

我得到以下结果:

[1,32768]

由于原始值是

00000001 00000000 00000000 10000000
1        0        0        128

我原以为它们会这样组合:

0000000100000000 0000000010000000
256              128

相反,我得到了这个:

0000000000000001 1000000000000000
1                32768

那是小端,对吧?我在我的 Mac 上运行此代码。我得到上面结果的原因是我的 Mac 使用小端吗?如果我在大端计算机上运行相同的代码,它会给出不同的结果吗? (我在 DartPad 上得到了相同的结果,但我不知道 DartPad 在什么机器上运行。)

解决方法

是的,预计会产生不同的结果。您将在大端系统上获得预期的结果。您当前查看字节数据的方法使用主机系统的字节序。这包括 DartPad,因为在 DartPad 中运行的代码正在编译为 JS,而 JS 仍然在同一个小端系统上运行。

Dart 语言没有固定的字节顺序。但是,某些查看字节数据的方法确实会像 ByteData 类那样显式设置字节顺序。

,

这是克里斯托弗·摩尔回答的一些附加信息。

您可以使用以下方法检查计算机的字节序:

print(Endian.host == Endian.little);

大多数个人计算机使用小端架构,因此通常会返回 true

您可以使用 ByteData 而不是 BytesBuffer 来指定查看数据的字节序:

import 'dart:typed_data';

void main() {
  Uint8List byteList = Uint8List.fromList([1,128]);
  ByteData byteData = ByteData.sublistView(byteList);

  int value = byteData.getUint16(0,Endian.big);
  print(value.toRadixString(2).padLeft(16,'0'));
  
  value = byteData.getUint16(2,'0'));
}

结果是:

0000000100000000 0000000010000000

如果您将 Endian.big 更改为 Endian.little,结果将是:

0000000000000001 1000000000000000

您可以在此处阅读更多相关信息: