Dart TypedData и представление с прямым / обратным порядком байтов
Если я запустил следующий код:
Uint8List bytes = Uint8List.fromList([1, 0, 0, 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, который по-прежнему работает в той же системе с прямым порядком байтов.
Для языка Dart нет установленного порядка следования байтов. Однако некоторые методы просмотра байтовых данных явно устанавливают порядок байтов, как и ByteData
класс.
Вот некоторая дополнительная информация к ответу Кристофера Мура.
Вы можете проверить порядок байтов на вашем компьютере с помощью следующего:
print(Endian.host == Endian.little);
Большинство персональных компьютеров используют архитектуру с прямым порядком байтов, так что она обычно возвращается true
.
Вы можете указать порядок байтов, с которым вы хотите просматривать данные, используя ByteData
вместо BytesBuffer
:
import 'dart:typed_data';
void main() {
Uint8List byteList = Uint8List.fromList([1, 0, 0, 128]);
ByteData byteData = ByteData.sublistView(byteList);
int value = byteData.getUint16(0, Endian.big);
print(value.toRadixString(2).padLeft(16, '0'));
value = byteData.getUint16(2, Endian.big);
print(value.toRadixString(2).padLeft(16, '0'));
}
Результат:
0000000100000000 0000000010000000
При изменении Endian.big
в Endian.little
результате будет:
0000000000000001 1000000000000000
Подробнее об этом можно прочитать здесь:
- Работа с байтами в Dart