一直一来,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'); } }