在 HTML 5 之前, JavaScript 操作二进制文件比较弱,各种方法效率低下,且容易产生错误。为此 HTML 5 新增了两种对象: ArrayBuffer 和 ArrayBufferView 。
ArrayBuffer 对象表示一个固定长度的二进制数据的缓存区。用户不能直接存取 ArrayBuffer 缓存区内容,必须通过 ArrayBufferView 对象来读写 ArrayBuffer 缓存区的内容。
创建方法如下:
var buffer = new ArrayBuffer(32);
参数为一个无符号长整型的整数,用于设置缓存区的长度,,单位为 byte 。 ArrayBuffer 缓存区创建成功后,该缓存区内的初始数据初始化为 0 。
ArrayBuffer 对象中包含 length 属性,该属性表示缓存区的长度。
HTML 5 使用 ArrayBufferView 对象以一种准确的格式来表示 ArrayBuffer 缓存区的数据。 HTML 5 不允许直接使用 ArrayBufferView 对象,而是使用 ArrayBufferView 的子类实例来读取 ArrayBuffer 缓存区的数据。
类型 | 字节长度 | 说明 |
---|---|---|
Int8Array | 1 | 8 位整数数组 |
Unit8Array | 1 | 8 位无符号整数数组 |
Unit8ClampedArray | 1 | 8 位无符号整数数组 |
Int16Array | 2 | 16 位整数数组 |
Unit16Array | 2 | 16 位无符号整数数组 |
Int32Array | 4 | 32 位整数数组 |
Unit32Array | 4 | 32 位无符号整数数组 |
Float32Array | 4 | 32 位 IEEE 浮点数数组 |
Float64Array | 8 | 32 位 IEEE 浮点数数组 |
上表中, Unit8ClampedArray 子类用于定义一种特殊的 8 位无符号整数数组,该数组的作用:代替 CanvasPixelArray 数组用于 Canvas API 中。该数组与普通的 8 位无符号整数数组的区别是,将 ArrayBuffer 缓存区的数值进行转换,内部使用箱位( clamping )算符,而不是模数( modulo )算法。
ArrayBufferView 数组的作用,可以根据同一个 ArrayBuffer 对象创建各种不同数字类型的数组。
在创建 ArrayBufferView 对象时,除了要指定 ArrayBuffer 缓存区外,还可以使用两个可选参数:
如果设置了 byteOffset 和 length 参数值,数组从 byteOffset 参数值指定的开始位置开始,【长度】 = 【 length 参数值所指定的元素个数】 * 【每个元素的字节长度】
。
如果忽略了 byteOffset 和 length 参数值,数组将跨越整个 ArrayBuffer 缓存区。
如果省略 length 参数值,数组将从 byteOffset 参数值指定的开始位置到 ArrayBuffer 缓存区的结束位置。
ArrayBufferView 对象包含 3 个属性∶
除了使用 ArrayBufferView 子类外,也可以使用 DataView 类存取 ArrayBuffer 缓存区的数据。
DataView 继承于, ArrayBufferView 类,提供了一些直接存取 ArrayBuffer 缓存区中数据的方法。
创建 DataView 对象的方法如下∶
var view = new DataView(buffer, byteOffset, byteLength);
如果设置了 byteOffset 和 byteLength 参数值, DataView 对象从 byteOffset 参数值所指定的开始位置开始,长度为 byteLength 参数值所指定的总字节长度。
如果忽略了 byteOffset 和 byteLength 参数值, DataView 对象跨越整个 ArrayBuffer 缓存区。如果省略 byteLength 参数值, DataView 对象将从 byteOffset 参数所指定的开始位置到 ArrayBuffer 缓存区的结束位置。
方法 | 说明 |
---|---|
getInt8(byteOffset) | 获取指定位置的一个 8 位整数值 |
getUnit8(byteOffset) | 获取指定位置的一个 8 位无符号整数值 |
getInt16(byteOffset,littleEndian) | 获取指定位置的一个 16 位整数值 |
getUnit16(byteOffset,littleEndian) | 获取指定位置的一个 16 位无符号整数值 |
getUnit32(byteOffset,littleEndian) | 获取指定位置的一个 32 位无符号整数值 |
getFloat32(byteOffset,littleEndian) | 获取指定位置的一个 32 位浮点数值 |
setFloat64(byteOffset,littleEndian) | 获取指定位置的一个 64 位浮点数值 |
setInt8(byteOffset,value) | 获取指定位置的一个 8 位整数值 |
setUnit8(byteOffset,value) | 设置指定位置的一个 8 位无符号整数值 |
setInt16(byteOffset,value,littleEndian) | 设置指定位置的一个 16 位整数值 |
setUnit16(byteOffset,value,littleEndian) | 设置指定位置的一个 16 位无符号整数值 |
setUnit32(byteOffset,value,littleEndian) | 设置指定位置的一个 32 位无符号整数值 |
setFloat32(byteOffset,value,littleEndian) | 设置指定位置的一个 32 位浮点数值 |
setFloat64(byteOffset,value,littleEndian) | 设置指定位置的一个 64 位浮点数值 |
window.onload = function () {
var result = document.getElementById('result');
var file = document.getElementById('file');
if (typeof FileReader == 'undefined') {
result.innerHTML = '<h1> 当前浏览器不支持 FileReader 对象 </h1>';
file.setAttribute('disabled', 'disabled');
}
};
function file_onchange() {
var file = document.getElementById('file').files[0];
if (!/image\/\w+/.test(file.type)) {
alert(' 请选择一个图像文件! ');
return;
}
var slice = file.slice(0, 4);
var reader = new FileReader();
reader.readAsArrayBuffer(slice);
var type;
reader.onload = function (e) {
var buffer = this.result;
var view = new DataView(buffer);
var magic = view.getInt32(0, false);
if (magic < 0) magic = magic + 0x100000000;
magic = magic.toString(16).toUpperCase();
if (magic.indexOf('FFD8FF') >= 0) type = 'jpg 文件 ';
if (magic.indexOf('89504E47') >= 0) type = 'png 文件 ';
if (magic.indexOf('47494638') >= 0) type = 'gif 文件 ';
if (magic.indexOf('49492A00') >= 0) type = 'tif 文件 ';
if (magic.indexOf('424D') >= 0) type = 'bmp 文件 ';
document.getElementById('result').innerHTML = ' 文件类型为: ' + type;
};
}