JAVASCRIPT之ArrayBuffer初探
考虑到用JAVASCRIPT来接收和处理服务器传来的二进制数据,则可以提高速度和节省带宽。作了一些实验,总结如下:
所以使用ArrayBuffer定义var bin作为二进制容器来进行转换。
使用charCodeAt来读取str中的内码,使用Uint8Array对bin赋值。
使用Uint16Array(相当于short)、Uint32Array(相当于long)来理解数据。
如果读取成两个short类型的整数就是0xffff,0x8080,它们的值用十进制显示出来是65536,32896。
如果读取成long就是0xffff8080,显示出来就是2155937791.
以上是最简单的例子,更多字节的二进制数据,增加数组长度即可。
获取arraybuffer的长度:
var binlen=bin.byteLength;
截取arraybuffer的部分:
var sub_bin=bin.slice(start,end);
还可以使用dataview来获取指定位置的数值:
用ajax获取服务器端的二进制数据,指定responseType为arraybuffer即可。
接下来本人做了一个复杂一些的实验,服务器发送过来混合数据,包含单字节整数、4字节整数和utf-8中英文字符串。
困难在于提取其中的utf-8字符串。网上高手的办法,可以成功:
如果原始二进制流是用utf16编码的话,处理起来会简单:
var str=String.fromCharCode.apply(null, new Uint16Array(buf));
还有大神用这种办法,使用Blob:
以上为事后总结,可能有些地方不准确。
<script> var str="\xff\xff\x80\x80"; var bin = new ArrayBuffer(4); var u8= new Uint8Array(bin); var u16= new Uint16Array(bin); var u32= new Uint32Array(bin); for(i=0;i<str.length;i++){ u8[i]=str[i].charCodeAt(); } document.write(u16[0]+","+u16[1]+"<br>"); document.write(u32[0]); </script>本例中var str模拟接收到的二进制原始数据,四字节。如果直接处理会被当做普通字符串,显示乱码。
所以使用ArrayBuffer定义var bin作为二进制容器来进行转换。
使用charCodeAt来读取str中的内码,使用Uint8Array对bin赋值。
使用Uint16Array(相当于short)、Uint32Array(相当于long)来理解数据。
如果读取成两个short类型的整数就是0xffff,0x8080,它们的值用十进制显示出来是65536,32896。
如果读取成long就是0xffff8080,显示出来就是2155937791.
以上是最简单的例子,更多字节的二进制数据,增加数组长度即可。
获取arraybuffer的长度:
var binlen=bin.byteLength;
截取arraybuffer的部分:
var sub_bin=bin.slice(start,end);
还可以使用dataview来获取指定位置的数值:
var view=new DataView(bin); var int32=view.getInt32(pos,4); var int16=view.getInt16(pos,2); var int8=view.getInt8(pos);
用ajax获取服务器端的二进制数据,指定responseType为arraybuffer即可。
xmlhttp.open("GET", Url,true); xmlhttp.responseType = 'arraybuffer'; xmlhttp.onreadystatechange = Recieve; xmlhttp.send(null);
接下来本人做了一个复杂一些的实验,服务器发送过来混合数据,包含单字节整数、4字节整数和utf-8中英文字符串。
困难在于提取其中的utf-8字符串。网上高手的办法,可以成功:
var bin_str=raw.slice(start,end);//raw为接收的混合数据 var carr=new Uint8Array(bin_str); var cstr=String.fromCharCode.apply(null,carr); var str=decodeURIComponent(escape(cstr));
如果原始二进制流是用utf16编码的话,处理起来会简单:
var str=String.fromCharCode.apply(null, new Uint16Array(buf));
还有大神用这种办法,使用Blob:
function ab2str(u,f) { //u 为arraybuffer, f为回调函数,接收转化后的数据 var b = new Blob([u]); var r = new FileReader(); r.readAsText(b, 'utf-8'); r.onload = function (){if(f)f.call(null,r.result)} }
以上为事后总结,可能有些地方不准确。
你可能想看: