摘要:引言近期,工作中發(fā)現(xiàn),有些前端小伙伴很少接觸到二進(jìn)制數(shù)據(jù),所以將項(xiàng)目中二進(jìn)制數(shù)據(jù)的應(yīng)用和大家分享一下,適合入門了解,高手慎入,歡迎拍磚。這樣,我們就完成了二進(jìn)制數(shù)據(jù)的請(qǐng)求解壓讀取和存儲(chǔ)了。
引言: 近期,工作中發(fā)現(xiàn),有些前端小伙伴很少接觸到二進(jìn)制數(shù)據(jù),所以將項(xiàng)目中二進(jìn)制數(shù)據(jù)的應(yīng)用和大家分享一下,適合入門了解,高手慎入,歡迎拍磚。項(xiàng)目背景: 基于公司原有圖形處理的二進(jìn)制數(shù)據(jù)文件(公司自定義的二進(jìn)制數(shù)據(jù)格式),實(shí)現(xiàn)Canvas繪圖。
話說:項(xiàng)目開始的時(shí)候我也是一臉懵逼,這么多技術(shù)難點(diǎn)需要攻克,1. 如何請(qǐng)求二進(jìn)制數(shù)據(jù)流?2. 如何解壓二進(jìn)制數(shù)據(jù)?3. 如何讀取二進(jìn)制數(shù)據(jù)?……
接下來我們一一攻破:見招拆招
1. 數(shù)據(jù)請(qǐng)求arraybuffer:基于ajax請(qǐng)求,設(shè)置接受的數(shù)據(jù)格式為arraybuffer類型,基于流文件的讀取是需要異步來處理的,否則數(shù)據(jù)可能有丟失。
let oReq = null; if (window.XMLHttpRequest) { oReq = new XMLHttpRequest(); } else { oReq = new ActiveXObject("Microsoft.XMLHTTP"); } oReq.onprogress = this.updateProgress;//下載進(jìn)度; oReq.responseType = "arraybuffer"; oReq.onload = function () { // 數(shù)據(jù)下載完成會(huì)觸發(fā); if ((oReq.status >= 200 && oReq.status < 300) || oReq.status == 304) { var arrayBuffer = oReq.response; // 接下來的任務(wù) ReadFromByteArray(arrayBuffer); //讀取收到的數(shù)據(jù) } if (oReq.status === 404) { alert("找不到對(duì)應(yīng)文件!") } }; oReq.open("GET", reqUrl, true); oReq.send(null);2. 數(shù)據(jù)讀取ArrayBuffer和DataView:
ArrayBuffer 對(duì)象用來表示通用的、固定長度的原始二進(jìn)制數(shù)據(jù)緩沖區(qū)。ArrayBuffer 不能直接操作,而是要通過類型數(shù)組對(duì)象或 DataView 對(duì)象來操作,它們會(huì)將緩沖區(qū)中的數(shù)據(jù)表示為特定的格式,并通過這些格式來讀寫緩沖區(qū)的內(nèi)容。2.1 校驗(yàn)數(shù)據(jù)的大小
function ReadFromByteArray(buffer){ parseInt(buffer.byteLength / 1024);//文件大小,單位KB; if (buffer.byteLength < 64) { // 失敗 console.log("文件格式不對(duì):長度小于64"); return false; } else { // 成功 解壓數(shù)據(jù) } }
DataView 視圖是一個(gè)可以從 ArrayBuffer 對(duì)象中讀寫多種數(shù)值類型的底層接口,在讀寫時(shí)不用考慮平臺(tái)字節(jié)序問題。
接下來我們可以創(chuàng)建一個(gè)DataView 對(duì)象實(shí)例,此方法適合順序存儲(chǔ)的數(shù)據(jù)讀取,非順序(如增量式存儲(chǔ)的數(shù)據(jù)不能按順序讀取,需要安裝table中索引讀取,否則會(huì)讀錯(cuò))。js提供了基本的二進(jìn)制讀取API,為了不用手動(dòng)計(jì)算偏移量,我們可以對(duì)基礎(chǔ)API進(jìn)行封裝,
DataView常用讀取數(shù)據(jù)的API
getFloat32() getFloat64() getInt16() getInt32() getInt8() getUint16() getUint32() getUint8()2.2 校驗(yàn)文件名稱
let dataView = new DataView(buffer, 0); //將上面獲取的buffer傳入到視圖中 let headstr = headerFiler.ReadUTFBytes(5);//讀取5個(gè)UTF8字節(jié),結(jié)果為文件格式 if (headstr != "DWG") { //DWG為文件的格式,存放在數(shù)據(jù)結(jié)構(gòu)的頭部 return false; }else{ // 繼續(xù)讀取數(shù)據(jù) }3. 數(shù)據(jù)解壓TypedArray和pako.js:
一個(gè)TypedArray 對(duì)象描述一個(gè)底層的二進(jìn)制數(shù)據(jù)緩存區(qū)的一個(gè)類似數(shù)組(array-like)視圖。事實(shí)上,沒有名為 TypedArray的全局對(duì)象,也沒有一個(gè)名為的 TypedArray構(gòu)造函數(shù)。相反,有許多不同的全局對(duì)象,下面會(huì)列出這些針對(duì)特定元素類型的類型化數(shù)組的構(gòu)造函數(shù)。在下面的頁面中,你會(huì)找到一些不管什么類型都公用的屬性和方法。
為了減少數(shù)據(jù)的傳入,后端會(huì)對(duì)二進(jìn)制數(shù)據(jù)進(jìn)行壓縮,前端難道要手寫解壓代碼?就算你敢寫,你是否敢用?當(dāng)然尋找三方插件,關(guān)于js二進(jìn)制數(shù)據(jù)的解壓插件還真不多,我選用了pako.js,移動(dòng)端暫為發(fā)現(xiàn)嚴(yán)重兼容性問題,PC端(IE)存在,一定慎用。期待推薦更加三方。
3.1 創(chuàng)建TypedArray先將buffer轉(zhuǎn)換為類型數(shù)組TypedArray,以便讀取和操控。
let compressdata = new Uint8Array(buffer, byteOffset, length);//把上面獲取`buffer`轉(zhuǎn)換成可操控的`TypedArray`。創(chuàng)建一個(gè)無符號(hào)整型的TypedArray,偏移量為byteOffset,長度為length。
Tips:偏移量為byteOffset類似于數(shù)組的索引,默認(rèn)為0, 設(shè)置后,從此開始讀取。如:
const compressdata = new Uint8Array(buffer, 4, 10);//從第4個(gè)字節(jié)開始讀取,長度為10個(gè)字節(jié)3.2 解壓數(shù)據(jù)
利用pako.js解壓數(shù)據(jù)
let uncompress = pako.inflate(compressdata);//解壓數(shù)據(jù); let uncompressdata = uncompress.buffer;// ArrayBuffer {} let dataViewData = new DataView(uncompressdata, 0);//解壓后數(shù)據(jù);
Tips:js中的number數(shù)據(jù)類型,無論數(shù)字的大小,都將占用8個(gè)字節(jié),即64位,就是Java 中double類型的長度;1字符串會(huì)占用2字節(jié),即16位。
js中此種規(guī)定,省去了我們聲明變量時(shí)對(duì)數(shù)據(jù)大小的計(jì)算,方便使用,但是,這樣就會(huì)造成浪費(fèi)大量的存儲(chǔ)空間,明顯增大數(shù)據(jù)的大小。及其不便于大數(shù)據(jù)的傳輸,所以會(huì)對(duì)數(shù)據(jù)進(jìn)行壓縮。
封裝數(shù)據(jù)讀取的API,避免手動(dòng)計(jì)算偏移量
function WsFiler(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 () { var b = this.dataView.getUint8(this.dataView.position); this.dataView.position++; return b; } WsFiler.prototype.ReadShort = function () { var s = this.dataView.getInt16(this.dataView.position, true); this.dataView.position += 2; return s; }; WsFiler.prototype.ReadInt32 = function () { var int32 = this.dataView.getInt32(this.dataView.position, true); this.dataView.position += 4; return int32; }; WsFiler.prototype.ReadUInt32 = function () { var uint32 = this.dataView.getUint32(this.dataView.position, true); this.dataView.position += 4; return uint32; } WsFiler.prototype.ReadUtf8String = function () { var len = this.ReadInt32();//字符串長度; return this.ReadUTFBytes(len); }; WsFiler.prototype.ReadFloat = function () { var ret = this.dataView.getFloat32(this.dataView.position, true); this.dataView.position += 4; return ret; }; WsFiler.prototype.ReadDouble = function () { var ret = this.dataView.getFloat64(this.dataView.position, true); this.dataView.position += 8; return ret; }4. 數(shù)據(jù)存儲(chǔ):
讀取到的數(shù)據(jù)可以任意操控,可以創(chuàng)建一個(gè)數(shù)組進(jìn)行存儲(chǔ)。便于我們的后續(xù)操控。數(shù)據(jù)的存儲(chǔ)就相對(duì)簡單了,根據(jù)需要將數(shù)據(jù)拆分即可。
這樣,我們就完成了二進(jìn)制數(shù)據(jù)的請(qǐng)求、解壓、讀取和存儲(chǔ)了。后續(xù)繼續(xù)分享,用canvas把我們讀到的數(shù)據(jù)畫到網(wǎng)頁上。
歡迎大家拍磚。不勝感謝!
參考文獻(xiàn):MDN
https://developer.mozilla.org...
https://developer.mozilla.org...
https://developer.mozilla.org...
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/94525.html
摘要:爬蟲是我接觸計(jì)算機(jī)編程的入門。練練練本文推薦的資源就是以項(xiàng)目練習(xí)帶動(dòng)爬蟲學(xué)習(xí),囊括了大部分爬蟲工程師要求的知識(shí)點(diǎn)。拓展閱讀一文了解爬蟲與反爬蟲最后,請(qǐng)注意,爬蟲的工作機(jī)會(huì)相對(duì)較少。 爬蟲是我接觸計(jì)算機(jī)編程的入門。哥當(dāng)年寫第一行代碼的時(shí)候別提有多痛苦。 本文旨在用一篇文章說透爬蟲如何自學(xué)可以達(dá)到找工作的要求。 爬蟲的學(xué)習(xí)就是跟著實(shí)際項(xiàng)目去學(xué),每個(gè)項(xiàng)目會(huì)涉及到不同的知識(shí)點(diǎn),項(xiàng)目做多了,自然...
摘要:不同于個(gè)人面經(jīng),這份面經(jīng)具有普適性。我在前面的文章中也提到了應(yīng)該怎么做自我介紹與項(xiàng)目介紹,詳情可以查看這篇文章備戰(zhàn)春招秋招系列初出茅廬的程序員該如何準(zhǔn)備面試。是建立連接時(shí)使用的握手信號(hào)。它表示確認(rèn)發(fā)來的數(shù)據(jù)已經(jīng)接受無誤。 showImg(https://segmentfault.com/img/remote/1460000016972448?w=921&h=532); 該文已加入開源文...
摘要:哪吒社區(qū)技能樹打卡打卡貼函數(shù)式接口簡介領(lǐng)域優(yōu)質(zhì)創(chuàng)作者哪吒公眾號(hào)作者架構(gòu)師奮斗者掃描主頁左側(cè)二維碼,加入群聊,一起學(xué)習(xí)一起進(jìn)步歡迎點(diǎn)贊收藏留言前情提要無意間聽到領(lǐng)導(dǎo)們的談話,現(xiàn)在公司的現(xiàn)狀是碼農(nóng)太多,但能獨(dú)立帶隊(duì)的人太少,簡而言之,不缺干 ? 哪吒社區(qū)Java技能樹打卡?【打卡貼 day2...
閱讀 2756·2021-11-25 09:43
閱讀 2121·2021-11-18 13:25
閱讀 4601·2021-09-22 15:52
閱讀 1882·2021-09-22 15:49
閱讀 2223·2019-08-30 15:54
閱讀 3016·2019-08-29 17:13
閱讀 2324·2019-08-29 16:54
閱讀 2263·2019-08-29 12:58