当前位置: 首页 > Web前端 > HTML5

前端进阶:二进制数据的操作-附项目代码

时间:2023-04-05 18:04:03 HTML5

介绍:最近在工作中发现有些前端小伙伴很少接触到二进制数据,所以想和大家分享一下二进制的应用项目中的数据。适合初学者了解,高手慎入,欢迎拍砖。项目背景:基于公司原始图形处理的二进制数据文件(公司定制的二进制数据格式),实现Canvas绘图。换句话说:项目开始时我很困惑。有太多的技术困难需要克服。1、如何请求一个二进制数据流?2.如何解压二进制数据?3、如何读取二进制数据?...接下来我们一一突破:看tricks1.数据请求arraybuffer:基于ajax请求,设置接受数据格式为arraybuffer类型,基于流文件读取需要异步处理,否则数据可能迷路了。让oReq=null;如果(window.XMLHttpRequest){oReq=newXMLHttpRequest();}else{oReq=newActiveXObject('Microsoft.XMLHTTP');}oReq.onprogress=this.updateProgress;//下载进度;o要求。responseType="数组缓冲区";oReq.onload=function(){//数据下载完成时触发;如果((oReq.status>=200&&oReq.status<300)||oReq.status==304){vararrayBuffer=oReq.response;//下一个任务ReadFromByteArray(arrayBuffer);//读取接收到的数据}if(oReq.status===404){alert("Couldnotfindthecorrespondingfile!")}};oReq.open("GET",reqUrl,true);oReq.send(null);2.数据读取ArrayBuffer和DataView:ArrayBuffer对象用于表示通用的、固定长度的原始二进制数据缓冲区。ArrayBuffer不能直接操作,必须通过类型数组对象或DataView对象进行操作,将缓冲区中的数据表示为特定格式,并通过这些格式读写缓冲区的内容。2.1校验数据大小functionReadFromByteArray(buffer){parseInt(buffer.byteLength/1024);//文件大小,单位KB;if(buffer.byteLength<64){//失败console.log("文件格式不正确:长度小于64");返回假;}else{//数据解压成功}}DataView视图是一个底层接口,可以从ArrayBuffer对象中读写多种数值类型,读写时不需要考虑平台字节顺序问题。接下来,我们可以创建一个DataView对象实例。这种方式适用于顺序存储的数据读取,而不是顺序读取(比如增量存储的数据不能顺序读取,需要安装表中的索引才能读取,否则会读错)。js提供了一个基本的二进制读取API。为了不用手动计算偏移量,我们可以封装基本的API。DataView读取数据常用APIgetFloat32()getFloat64()getInt16()getInt32()getInt8()getUint16()getUint32()getUint8()2.2校验文件名letdataView=newDataView(buffer,0);//将上面获得的缓冲区传递到视图中letheadstr=headerFiler.ReadUTFBytes(5);//读取5个UTF8字节,结果为文件格式数据}3.数据解压缩TypedArray和pako.js:TypedArray对象描述了底层二进制数据缓冲区的类似数组的视图。实际上,不存在名为TypedArray的全局对象,也不存在名为TypedArray的构造函数。相反,有许多不同的全局对象,其用于特定元素类型的类型化数组的构造函数如下所列。在接下来的几页中,您将找到所有类型共有的一些属性和方法。为了减少传入的数据,后端会对二进制数据进行压缩。前端是不是要手写解压代码?就算你敢写,你敢用吗?当然找第三方插件,解压js二进制数据的插件不多,我选择了pako。期待推荐更多三方。3.1创建TypedArray首先将buffer转换为类型化数组TypedArray,用于读取和操作。letcompressdata=newUint8Array(buffer,byteOffset,length);//将上面得到的`buffer`转换为可操作的`TypedArray`。创建具有偏移量byteOffset和长度length的无符号整数的TypedArray。Tips:偏移量为byteOffset,类似于数组的索引。默认为0。设置后,从这里读取。例如:constcompressdata=newUint8Array(buffer,4,10);//从第4字节开始读取,长度为10字节3.2解压数据使用pako.js解压数据letuncompress=pako.inflate(compressdata);//解压数据;letuncompressdata=uncompress.buffer;//ArrayBuffer{}letdataViewData=newDataView(uncompressdata,0);//解压数据;Tips:js中的number数据类型,无论数字大小,Both都会占用8个字节,即64位,这是Java中double类型的长度;1个字符串会占用2个字节,即16位。js中的这种规定省去了我们声明变量时数据大小的计算,使用起来方便,但是会造成存储空间的大量浪费,数据的大小也会明显增加。大数据传输不方便,所以数据会被压缩。封装数据读取的API,避免手动计算偏移量functionWsFiler(dataView){this.dataView=dataView;this.dataView.position=0;}WsFiler.SEEK_BEGIN=0;WsFiler.SEEK_SET=0;WsFiler.SEEK_CUR=1;WsFiler.SEEK_END=2;WsFiler.prototype.ReadByte=function(){varb=this.dataView.getUint8(this.dataView.position);这个.dataView.position++;返回b;}WsFiler.prototype.ReadShort=function(){vars=this.dataView.getInt16(this.dataView.position,true);这个.dataView.position+=2;返回s;};WsFiler.prototype.ReadInt32=function(){varint32=this.dataView.getInt32(this.dataView.position,true);这个.dataView.position+=4;returnint32;};WsFiler.prototype.ReadUInt32=function(){varuint32=this.dataView.getUint32(this.dataView.position,true);这个.dataView.position+=4;returnuint32;}WsFiler.prototype.ReadUtf8String=function(){varlen=this.ReadInt32();//字符长度;returnthis.ReadUTFBytes(len);};WsFiler.prototype.ReadFloat=function(){varret=this.dataView.getFloat32(this.dataView.position,true);这个.dataView.position+=4;returnret;};WsFiler.prototype.ReadDouble=function(){varret=this.dataView.getFloat64(this.dataView.position,true);这个.dataView.position+=8;returnret;}4.数据存储:读取的数据可以任意操作,可以创建一个数组进行存储存储方便我们后续的操作。数据存储比较简单,按需要拆分数据即可。这样,我们就完成了对二进制数据的请求、解压、读取和存储。后面继续分享,用canvas画出我们在网页上读取的数据。欢迎大家拍砖。非常感谢!参考资料:MDNhttps://developer.mozilla.org...https://developer.mozilla.org...https://developer.mozilla.org...