JavaScript前端开发之实现二进制读写操作
关于javascript前端开发之实现二进制读写操作的相关介绍,请看以下内容详解,本文介绍的非常详细,具有参考价值。
由于种种原因,在浏览器中无法像nodejs那样操作二进制。
最近写了一个在浏览器端操作读写二进制的帮助类
!function(entrance){ "usestrict"; if("object"===typeofexports&&"undefined"!==typeofmodule){ module.exports=entrance(); }elseif("function"===typeofdefine&&define.amd){ define([],entrance()); }else{ varf; if("undefined"!==typeofwindow){ f=window; }else{ thrownewError('wrongexecutionenvironment'); } f.TinyStream=entrance(); } }(function(){ varbinaryPot={ /** *初始化字节流,把-128至128的区间改为0-256的区间.便于计算 *@param{Array}array字节流数组 *@return{Array}转化好的字节流数组 */ init:function(array){ for(vari=0;i<array.length;i++){ array[i]*=1; if(array[i]<0){ array[i]+=256 } if(array[i]>255){ thrownewError('不合法字节流') } } returnarray; }, /** *把一段字符串按照utf8编码写到缓冲区中 *@param{String}str将要写入缓冲区的字符串 *@param{Boolean}isGetBytes是否只得到内容字节(不包括最开始的两位占位字节) *@returns{Array}字节流 */ writeUTF:function(str,isGetBytes){ varback=[], byteSize=0; for(vari=0;i<str.length;i++){ varcode=str.charCodeAt(i); if(code>=0&&code<=127){ byteSize+=1; back.push(code); }elseif(code>=128&&code<=2047){ byteSize+=2; back.push((192|(31&(code>>6)))); back.push((128|(63&code))) }elseif(code>=2048&&code<=65535){ byteSize+=3; back.push((224|(15&(code>>12)))); back.push((128|(63&(code>>6)))); back.push((128|(63&code))) } } for(i=0;i<back.length;i++){ if(back[i]>255){ back[i]&=255 } } if(isGetBytes){ returnback } if(byteSize<=255){ return[0,byteSize].concat(back); }else{ return[byteSize>>8,byteSize&255].concat(back); } }, /** *把一串字节流按照utf8编码读取出来 *@paramarr字节流 *@returns{String}读取出来的字符串 */ readUTF:function(arr){ if(Object.prototype.toString.call(arr)=="[objectString]"){ returnarr; } varUTF="", _arr=this.init(arr); for(vari=0;i<_arr.length;i++){ varone=_arr[i].toString(2), v=one.match(/^1+?(?=0)/); if(v&&one.length==8){ varbytesLength=v[0].length, store=_arr[i].toString(2).slice(7-bytesLength); for(varst=1;st<bytesLength;st++){ store+=_arr[st+i].toString(2).slice(2) } UTF+=String.fromCharCode(parseInt(store,2)); i+=bytesLength-1 }else{ UTF+=String.fromCharCode(_arr[i]) } } returnUTF }, /** *转换成Stream对象 *@paramx *@returns{Stream} */ convertStream:function(x){ if(xinstanceofStream){ returnx }else{ returnnewStream(x) } }, /** *把一段字符串转为mqtt格式 *@paramstr *@returns{*|Array} */ toMQttString:function(str){ returnthis.writeUTF(str) } }; /** *读取指定长度的字节流到指定数组中 *@param{Stream}mStream实例 *@param{number}i读取的长度 *@param{Array}a存入的数组 *@returns{Array}存入的数组 */ functionbaseRead(m,i,a){ vart=a?a:[]; for(varstart=0;start<i;start++){ t[start]=m.pool[m.position++] } returnt } /** *判断浏览器是否支持ArrayBuffer */ varsupportArrayBuffer=(function(){ return!!window.ArrayBuffer; })(); /** *字节流处理实体类 *@param{String|Array}array初始化字节流,如果是字符串则按照UTF8的格式写入缓冲区 *@constructor */ functionStream(array){ if(!(thisinstanceofStream)){ returnnewStream(array); } /** *字节流缓冲区 *@type{Array} */ this.pool=[]; if(Object.prototype.toString.call(array)==='[objectArray]'){ this.pool=binaryPot.init(array); }elseif(Object.prototype.toString.call(array)=="[objectArrayBuffer]"){ vararr=newInt8Array(array); this.pool=binaryPot.init([].slice.call(arr)); }elseif(typeofarray==='string'){ this.pool=binaryPot.writeUTF(array); } varself=this; //当前流执行的起始位置 this.position=0; //当前流写入的多少字节 this.writen=0; //返回当前流执行的起始位置是否已经大于整个流的长度 this.check=function(){ returnself.position>=self.pool.length }; } /** *强制转换为Stream对象 *@paramx *@returns{*|Stream} */ Stream.parse=function(x){ returnbinaryPot.convertStream(x); }; Stream.prototype={ /** *从缓冲区读取4个字节的长度并转换为int值,position往后移4位 *@returns{Number}读取到的数字 *@description如果position大于等于缓冲区的长度则返回-1 */ readInt:function(){ if(this.check()){ return-1 } varend=""; for(vari=0;i<4;i++){ end+=this.pool[this.position++].toString(16) } returnparseInt(end,16); }, /** *从缓冲区读取1个字节,position往后移1位 *@returns{Number} *@description如果position大于等于缓冲区的长度则返回-1 */ readByte:function(){ if(this.check()){ return-1 } varval=this.pool[this.position++]; if(val>255){ val&=255; } returnval; }, /** *从缓冲区读取1个字节,或读取指定长度的字节到传入的数组中,position往后移1或bytesArray.length位 *@param{Array|undefined}bytesArray *@returns{Array|Number} */ read:function(bytesArray){ if(this.check()){ return-1 } if(bytesArray){ returnbaseRead(this,bytesArray.length|0,bytesArray) }else{ returnthis.readByte(); } }, /** *从缓冲区的position位置按UTF8的格式读取字符串,position往后移指定的长度 *@returns{String}读取的字符串 */ readUTF:function(){ varbig=(this.readByte()<<8)|this.readByte(); returnbinaryPot.readUTF(this.pool.slice(this.position,this.position+=big)); }, /** *把字节流写入缓冲区,writen往后移指定的位 *@param{Number|Array}_byte写入缓冲区的字节(流) *@returns{Array}写入的字节流 */ write:function(_byte){ varb=_byte; if(Object.prototype.toString.call(b).toLowerCase()=="[objectarray]"){ [].push.apply(this.pool,b); this.writen+=b.length; }else{ if(+b==b){ if(b>255){ b&=255; } this.pool.push(b); this.writen++ } } returnb }, /** *把参数当成char类型写入缓冲区,writen往后移2位 *@param{Number}v写入缓冲区的字节 */ writeChar:function(v){ if(+v!=v){ thrownewError("writeChar:argumentstypeiserror") } this.write((v>>8)&255); this.write(v&255); this.writen+=2 }, /** *把字符串按照UTF8的格式写入缓冲区,writen往后移指定的位 *@param{String}str字符串 *@return{Array}缓冲区 */ writeUTF:function(str){ varval=binaryPot.writeUTF(str); [].push.apply(this.pool,val); this.writen+=val.length; }, /** *把缓冲区字节流的格式从0至256的区间改为-128至128的区间 *@returns{Array}转换后的字节流 */ toComplements:function(){ var_tPool=this.pool; for(vari=0;i<_tPool.length;i++){ if(_tPool[i]>128){ _tPool[i]-=256 } } return_tPool }, /** *获取整个缓冲区的字节 *@param{Boolean}isCom是否转换字节流区间 *@returns{Array}转换后的缓冲区 */ getBytesArray:function(isCom){ if(isCom){ returnthis.toComplements() } returnthis.pool }, /** *把缓冲区的字节流转换为ArrayBuffer *@returns{ArrayBuffer} *@throw{Error}不支持ArrayBuffer */ toArrayBuffer:function(){ if(supportArrayBuffer){ returnnewArrayBuffer(this.getBytesArray()); }else{ thrownewError('notsupportarraybuffer'); } }, clear:function(){ this.pool=[]; this.writen=this.position=0; } }; returnStream; });
如何使用?
<scriptsrc="binary.js"></script> <script> varts=TinyStream('我叫张亚涛'); ts.writeUTF('你好'); console.log('获取缓冲区字节流:',ts.getBytesArray()); console.log('当前的缓冲区position为:',ts.position,'writen为:',ts.writen); console.log('读取第一个utf8字节流:',ts.readUTF()); console.log('当前的缓冲区position为:',ts.position,'writen为:',ts.writen); console.log('读取第二个utf8字节流:',ts.readUTF()); console.log('当前的缓冲区position为:',ts.position,'writen为:',ts.writen); </script>
以后,我可以不用为浏览器段处理二进制而发愁了!!!希望本文分享对大家学习javascript二进制相关知识有所帮助。