一直一来,JavaScritp都缺少处理二进制数据的能力。唯一算是跟二进制数据有点关系的是String的charCodeAt()和fromCharCode()方法。
HTML5以来,JavaScript增加了新的数据类型,从而对二进制数据有了一定程度上的支持。
其中最主要的数据类型是ArrayBuffer,用来表示一串bytes。
对二进制数据的处理则交由不同的ArrayBufferView来处理,比如:
字节序使用本机的字节序。
var buffer = new ArrayBuffer(2); var bytes = Uint8Array(buffer); var value = bytes[1];
另一个更底层的接口是DataView,提供了一组方法用于读取或修改ArrayBuffer
var buffer = new ArrayBuffer(2); var view = new DataView(buffer); var little_endian = true; view.setInt16(0, 256, little_endian); // use little endian view.getInt16(0, little_endian );
二进制世界不可避免地涉及到Big Endian和Little Endian的问题。
下面的代码可以用于判断本机的字节序。
// 引自:https://developer.mozilla.org/en-US/docs/Web/API/DataView
var littleEndian = (function() {
var buffer = new ArrayBuffer(2);
new DataView(buffer).setInt16(0, 256, true);
return new Int16Array(buffer)[0] === 256;
})();
怎样把二进制数据传送给JavaScript呢?
一种方法是利用base64编码,通过window.atob函数转换为“字符串”,再逐字节赋值给ArrayBuffer:
function base64tobin(base64) {
var text = window.atob(base64);
var buffer = new ArrayBuffer(text.length);
var view = new DataView(buffer);
for(var i=0, n=text.length; i<n; i++) view.setUint8(i,text.charCodeAt(i));
return buffer;
}
window.btoa()可以把数据编码为base64。
二进制数据转为字符串,显然是和字符串的编码问题相关的。
function bin2txt(buffer,encoding) {
if(encoding=='ascii'){
return String.fromCharCode.apply(null, new Uint8Array(buffer));
}else if(encoding=='unicode' || encoding=='utf16'){
return String.fromCharCode.apply(null, new Uint16Array(buffer)); // 使用本机字节序
}else{
alert('Not supported yet');
}
}