DataView视图
如果一段数据包括多种类型(比如服务器传来的HTTP数据),这时除了建立ArrayBuffer对象的复合视图以外,还可以通过DataView视图进行操作。
DataView视图提供更多操作选项,而且支持设定字节序。本来,在设计目的上,ArrayBuffer对象的各种类型化视图,是用来向网卡、声卡之类的本机设备传送数据,所以使用本机的字节序就可以了;而DataView的设计目的,是用来处理网络设备传来的数据,所以大端字节序或小端字节序是可以自行设定的。
DataView本身也是构造函数,接受一个ArrayBuffer对象作为参数,生成视图。
DataView(ArrayBuffer buffer [, 字节起始位置 [, 长度]]);
下面是一个实例。
var buffer = new ArrayBuffer(24);var dv = new DataView(buffer);
实例2: 使用DataView还可以避免一些异常
//将字符串转换成 Blob对象var blob = new Blob(['中文字符串'], { type: 'text/plain'});//将Blob 对象转换成 ArrayBuffervar reader = new FileReader();reader.readAsArrayBuffer(blob);reader.onload = function (e) { console.info(reader.result); //ArrayBuffer {} //经常会遇到的异常 Uncaught RangeError: byte length of Int16Array should be a multiple of 2 //var buf = new int16array(reader.result); //console.info(buf); //将 ArrayBufferView 转换成Blob var buf = new DataView(reader.result); console.info(buf); //DataView {} reader.readAsText(new Blob([buf]), 'utf-8'); reader.onload = function () { console.info(reader.result); //中文字符串 };}
DataView视图提供以下方法读取内存:
- getInt8:读取1个字节,返回一个8位整数。
- getUint8:读取1个字节,返回一个无符号的8位整数。
- getInt16:读取2个字节,返回一个16位整数。
- getUint16:读取2个字节,返回一个无符号的16位整数。
- getInt32:读取4个字节,返回一个32位整数。
- getUint32:读取4个字节,返回一个无符号的32位整数。
- getFloat32:读取4个字节,返回一个32位浮点数。
- getFloat64:读取8个字节,返回一个64位浮点数。
这一系列get方法的参数都是一个字节序号,表示从哪个字节开始读取。
var buffer = new ArrayBuffer(24);var dv = new DataView(buffer);// 从第1个字节读取一个8位无符号整数var v1 = dv.getUint8(0);// 从第2个字节读取一个16位无符号整数var v2 = dv.getUint16(1); // 从第4个字节读取一个16位无符号整数var v3 = dv.getUint16(3);
上面代码读取了ArrayBuffer对象的前5个字节,其中有一个8位整数和两个十六位整数。
如果一次读取两个或两个以上字节,就必须明确数据的存储方式,到底是小端字节序还是大端字节序。默认情况下,DataView的get方法使用大端字节序解读数据,如果需要使用小端字节序解读,必须在get方法的第二个参数指定true。
// 小端字节序var v1 = dv.getUint16(1, true);// 大端字节序var v2 = dv.getUint16(3, false);// 大端字节序var v3 = dv.getUint16(3);
DataView视图提供以下方法写入内存:
- setInt8:写入1个字节的8位整数。
- setUint8:写入1个字节的8位无符号整数。
- setInt16:写入2个字节的16位整数。
- setUint16:写入2个字节的16位无符号整数。
- setInt32:写入4个字节的32位整数。
- setUint32:写入4个字节的32位无符号整数。
- setFloat32:写入4个字节的32位浮点数。
- setFloat64:写入8个字节的64位浮点数。
这一系列set方法,接受两个参数,第一个参数是字节序号,表示从哪个字节开始写入,第二个参数为写入的数据。对于那些写入两个或两个以上字节的方法,需要指定第三个参数,false或者undefined表示使用大端字节序写入,true表示使用小端字节序写入。
// 在第1个字节,以大端字节序写入值为25的32位整数dv.setInt32(0, 25, false); // 在第5个字节,以大端字节序写入值为25的32位整数dv.setInt32(4, 25); // 在第9个字节,以小端字节序写入值为2.5的32位浮点数dv.setFloat32(8, 2.5, true);
如果不确定正在使用的计算机的字节序,可以采用下面的判断方式。
var littleEndian = (function() { var buffer = new ArrayBuffer(2); new DataView(buffer).setInt16(0, 256, true); return new Int16Array(buffer)[0] === 256;})();
如果返回true,就是小端字节序;如果返回false,就是大端字节序。
属性:
Read onlyThe referenced by this view. Fixed at construction time and thus read only.
Read onlyThe length (in bytes) of this view from the start of its . Fixed at construction time and thus read only.
Read onlyThe offset (in bytes) of this view from the start of its . Fixed at construction time and thus read only.
更多类型化数组:
更多DataView: