1、什么事字节序?

字节序指的是数值在内存中的表示方式。

const buffer = new ArrayBuffer(16);
const int32View = new Int32Array(buffer); for (let i = 0; i < int32View.length; i++) {
int32View[i] = i * 2;
}

上面代码生成一个 16 字节(16字节 * 8位 = 128位)ArrayBuffer对象,然后在它的基础上,建立了一个 32 位整数的视图。由于每个 32 位整数占据 4 个字节,所以一共可以写入 4 个整数,依次为 0,2,4,6。

如果在这段数据上接着建立一个 16 位整数的视图,则可以读出完全不一样的结果。

const int16View = new Int16Array(buffer);

for (let i = 0; i < int16View.length; i++) {
console.log("Entry " + i + ": " + int16View[i]);
}
// Entry 0: 0
// Entry 1: 0
// Entry 2: 2
// Entry 3: 0
// Entry 4: 4
// Entry 5: 0
// Entry 6: 6
// Entry 7: 0

由于每个 16 位整数占据 2 个字节,所以整个ArrayBuffer对象现在分成 8 段。然后,由于 x86 体系的计算机都采用小端字节序(little endian),相对重要的字节排在后面的内存地址,相对不重要字节排在前面的内存地址,所以就得到了上面的结果。

比如,一个占据四个字节的 16 进制数0x12345678,决定其大小的最重要的字节是“12”,最不重要的是“78”。小端字节序将最不重要的字节排在前面,储存顺序就是78563412;大端字节序则完全相反,将最重要的字节排在前面,储存顺序就是12345678。目前,所有个人电脑几乎都是小端字节序,所以 TypedArray 数组内部也采用小端字节序读写数据,或者更准确的说,按照本机操作系统设定的字节序读写数据。

这并不意味大端字节序不重要,事实上,很多网络设备特定的操作系统采用的是大端字节序。这就带来一个严重的问题:如果一段数据是大端字节序,TypedArray 数组将无法正确解析,因为它只能处理小端字节序!为了解决这个问题,JavaScript 引入DataView对象,可以设定字节序,下文会详细介绍。

下面是另一个例子。

// 假定某段buffer包含如下字节 [0x02, 0x01, 0x03, 0x07]
const buffer = new ArrayBuffer(4);
const v1 = new Uint8Array(buffer);
v1[0] = 2;
v1[1] = 1;
v1[2] = 3;
v1[3] = 7; const uInt16View = new Uint16Array(buffer); // 计算机采用小端字节序
// 所以头两个字节等于258
if (uInt16View[0] === 258) {
console.log('OK'); // "OK"
} // 赋值运算
uInt16View[0] = 255; // 字节变为[0xFF, 0x00, 0x03, 0x07]
uInt16View[0] = 0xff05; // 字节变为[0x05, 0xFF, 0x03, 0x07]
uInt16View[1] = 0x0210; // 字节变为[0x05, 0xFF, 0x10, 0x02]

2、如何判断大小段字节序?

下面的函数可以用来判断,当前视图是小端字节序,还是大端字节序。

const BIG_ENDIAN = Symbol('BIG_ENDIAN');
const LITTLE_ENDIAN = Symbol('LITTLE_ENDIAN'); function getPlatformEndianness() {
let arr32 = Uint32Array.of(0x12345678);
let arr8 = new Uint8Array(arr32.buffer);
switch ((arr8[0]*0x1000000) + (arr8[1]*0x10000) + (arr8[2]*0x100) + (arr8[3])) {
case 0x12345678:
return BIG_ENDIAN;
case 0x78563412:
return LITTLE_ENDIAN;
default:
throw new Error('Unknown endianness');
}
}

总之,与普通数组相比,TypedArray 数组的最大优点就是可以直接操作内存,不需要数据类型转换,所以速度快得多。

Reference:

http://es6.ruanyifeng.com/#docs/arraybuffer#%E5%AD%97%E8%8A%82%E5%BA%8F

ES6中ArrayBuffer与计算机字节序的更多相关文章

  1. C语言中的位域、字节序、比特序、大小端

    转:http://www.360doc.com/content/13/0624/10/496343_295125641.shtml 1.比特序 / 位序 /  bit numbering / bit  ...

  2. 刨根究底字符编码之十一——UTF-8编码方式与字节序标记

    UTF-8编码方式与字节序标记 一.UTF-8编码方式 1. 接下来将分别介绍Unicode字符集的三种编码方式:UTF-8.UTF-16.UTF-32.这里先介绍应用最为广泛的UTF-8. 为满足基 ...

  3. 字节序(Endian),大端(Big-Endian),小端(Little-Endian)

    http://www.cppblog.com/tx7do/archive/2009/01/06/71276.html 在各种计算机体系结构中,对于字节.字等的存储机制有所不同,因而引发了计算机通信领域 ...

  4. 一步一图带你深入剖析 JDK NIO ByteBuffer 在不同字节序下的设计与实现

    让我们来到微观世界重新认识 Netty 在前面 Netty 源码解析系列 <聊聊 Netty 那些事儿>中,笔者带领大家从宏观世界详细剖析了 Netty 的整个运转流程.从一个网络数据包在 ...

  5. 判断.net中在windows系统下的字节序

    字节序,是指字节在内存中的存储顺序.其又分为大端字节(Big-Endian)序和小端字节序(Little-Endian). 以下摘自百度百科: a) Little-Endian就是低位字节排放在内存的 ...

  6. js arrayBuffer 字节序问题,小端法,大端法

    原文博客 { var buffer = new ArrayBuffer(2) var bytes = new Uint16Array(buffer) bytes[0] = (65 << 8 ...

  7. LITTLE-ENDIAN(小字节序、低字节序) BOM——Byte Order Mark 字节序标记 数据在内存中的存放顺序

    总结: 1. endian 字节存放次序 字节序,顾名思义字节的顺序,再多说两句就是大于一个字节类型的数据在内存中的存放顺序(一个字节的数据当然就无需谈顺序的问题了). 2. LITTLE-ENDIA ...

  8. socket编程相关的结构体和字节序转换、IP、PORT转换函数

    注意:结构体之间不能直接进行强制转换, 必须先转换成指针类型才可以进行结构体间的类型转换, 这里需要明确的定义就是什么才叫强制转换. 强制转换是将内存中一段代码以另一种不同类型的方式进行解读, 因此转 ...

  9. 各种编码中汉字所占字节数;中文字符集编码Unicode ,gb2312 , cp936 ,GBK,GB18030

    vim settings set fileencodings=utf-8,ucs-bom,gb18030,gbk,gb2312,cp936,latin1set termencoding=utf-8se ...

随机推荐

  1. Linux SELinux 使用操作

    Linux SELinux 使用操作 # 修改 SELinux 启动模式.临时生效 命令:setenforce [0|1] 0:转成 permissive 宽容模式: 1:转成 Enforcing 强 ...

  2. WPF ListView ,XML

    <?xml version="1.0" encoding="utf-8" ?><PersonList> <Person Id=&q ...

  3. MySQL基础(一)(启动/停止、登录/退出、语法规范及最基础操作)

    1.启动/停止MySQL服务 启动:net start mysql    停止:net stop mysql 2.MySQL登录/退出 登录:mysql 参数:如果连接的是本地服务器,一般用命令:my ...

  4. .Net 高级 模拟事件模型

    第一步:创建一个类,并继承:IHttpModule using System; using System.Collections.Generic; using System.Linq; using S ...

  5. mac下安装php7.2、mysql5.7、nginx环境

    本篇文章是通过homebrew安装,home brew对于Mac相当于centos 的yum一样方便简单,大家可以先去安装home brew.网上很多简单靠谱的例子,这里不写了 一.准备条件为了安装最 ...

  6. 让windows 10 家庭版 支持 Hyper-v 的方法

    pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*Hyper-V*.mum >hyper-v.txt for /f ...

  7. JAVA性能监控与调优参考文档链接

    JAVA性能监控与调优参考文档链接 jdk8工具集 https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.htmlTroub ...

  8. 轻量级手绘软件openCanvas免费版,手绘板CG手绘软件

    轻量级手绘软件openCanvas免费版,手绘板CG手绘软件 手绘软件通俗一点来说就是用手来绘画的软件,应用很宽泛如建筑,服饰陈列设计.橱窗设计.家居软装设计.空间花艺设计.美术.园林.环艺.摄影.工 ...

  9. 关于css中布局遇到的一些问题

    现在本人初学网页布局经常遇到一些布局问题比如图片错位. 遇到的问题以及解决方案如下 行内元素有缝隙 块级元素没有缝隙 行内块元素中间会有小缝隙    常见的解决办法就是浮动

  10. MQTT实战2 - 使用MQTTnet实现mqtt通信

    MQTT实战1 - 使用Apache Apollo代理服务器实现mqtt通信 MQTT实战2 - 使用MQTTnet实现mqtt通信 源码下载 -> 提取码  QQ:505645074 MQTT ...