问答 百科手机端

JAVASCRIPT之ArrayBuffer初探

2023-03-14 15:59
考虑到用JAVASCRIPT来接收和处理服务器传来的二进制数据,则可以提高速度和节省带宽。作了一些实验,总结如下:

<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)}
 }



以上为事后总结,可能有些地方不准确。
热门