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 对象转换成 ArrayBuffer
var 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,就是大端字节序。

属性:

DataView.prototype.buffer

 Read onlyThe ArrayBuffer referenced by this view. Fixed at construction time and thus read only.

DataView.prototype.byteLength 

Read onlyThe length (in bytes) of this view from the start of its ArrayBuffer. Fixed at construction time and thus read only.

DataView.prototype.byteOffset 

Read onlyThe offset (in bytes) of this view from the start of its ArrayBuffer. Fixed at construction time and thus read only.

更多类型化数组:http://www.cnblogs.com/tianma3798/p/4294433.html

更多DataView:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView