999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

基于自適應分片的大文件快速上傳①

2022-08-04 09:58:36周煜瑩崔巖松王丹志陳科良
計算機系統應用 2022年7期
關鍵詞:方法

周煜瑩,崔巖松,王丹志,陳科良

(北京郵電大學 電子工程學院,北京 100876)

在計算機網絡技術迅猛發展的今天,文件的上傳是一個重要的應用交互場景. 對于普通的圖片或word文檔等幾十KB 或者幾MB 的文件上傳,使用Web 的組件即可完成流暢的上傳功能. 通常的文件上傳是一次性獲取整個文件上傳,傳輸過程簡單: 第1 步獲取本地文件,第2 步將文件轉換成字節傳輸,第3 步后端接收按順序接收字節到內存中,最后將接收完的字節保存為文件[1]. 但在大文件傳輸的應用中,例如在郵箱管理系統中上傳大容量的資源壓縮包,在網絡視頻發布系統中上傳視頻文件,在線制作電子相冊時需要上傳高清圖片,網絡硬盤服務系統,局域網文件交換系統等[2]. 這些業務場景下的大文件傳輸很容易占據較大的帶寬資源,造成網頁訪問速度降低,也可能導致后端服務器響應超時,前端頁面長時間無響應,甚至卡頓而導致頁面崩潰. 即便能夠上傳成功,用戶需要較長的等待時間,在此期間不能刷新頁面,只能等待請求完成. 這些問題嚴重降低了用戶體驗,因而大文件上傳一直是Web 應用系統的一大痛點.

針對以上問題,本文基于Node.js 邊讀邊寫的流模式傳輸,采用HTML5 的File API 對上傳的大文件進行分片處理,通過上傳速率動態調整分片大小,同時充分利用帶寬,結合多并發上傳進一步縮短上傳時間,在服務端檢驗所有分片文件上傳完整后,再進行文件的合并,有效的提高了大文件的上傳速率,減少了用戶的等待時長.

1 文件上傳的常用方式

目前,基于HTTP 協議的文件上傳方式有以下幾種:

(1)表單上傳

這是Web 開發中最常見的上傳方式,使用Form表單的input[type=“input”]打開文件選擇界面,通過POST 方法向指定資源提交表單數據[3]. 上傳的文件使用multipart 格式,編碼類型為“multipart/form-data”[4].

(2)無刷新的Ajax 上傳

區別于表單上傳,使用Ajax 的異步上傳,在提交表單數據不需要刷新和跳轉頁面. 提交數據時,可以使用FormData 對象模擬表單提交,發送表單的二進制文件內容,通過XMLHttpRequest 實例將參數提交至服務端[5].

(3)Flash 上傳

在傳統表單的上傳功能基礎上,Flash 上傳方式在不刷新網頁的條件下,支持多個文件批量上傳以及顯示上傳進度等功能. 它采用Flash 作為中間代理層與服務端進行通信,以此為基礎的SWFUpload、Plupload及Uploadify 等文件上傳插件被廣泛應用[6].

(4)第三方組件上傳/插件上傳

插件技術主要包括ActiveX、Applet 等,雖然可能受限于瀏覽器的安全性設置,但在學校及企業內部網站環境中有一定的使用價值[7]. 例如ActiveX 組件,在VB 6.0 運行環境下,使用關鍵的Winsock 控件來建立與服務端之間的通信,通過Socket 連接發送文件數據.文獻[8]對FileUpload,SWFUpload 及SlickUpload 三種組件的特性進行了分析和評估. FileUpload 控件使用簡單,但默認對上傳組件的大小有限制,因而需要通過修改配置文件中響應時間和大小的限制實現大文件的上傳. SWFUpload 作為一個開源的JavaScript 和Flash庫,它結合了二者的功能,可以實現交互性更好的界面展示. Slickupload 是來自國外的商業組件,其在局域網的文件上傳中具有良好的表現[8].

2 關鍵技術

2.1 Node.js

Node.js 基于事件驅動的非阻塞I/O 模型,旨在支持能夠管理大量并發請求的輕量級服務器的簡單而快速的開發[9]. 受益于V8,Node.js 性能優越,運行速度快,可以在服務端運行,匿名函數和閉包的使用使其在語言層面具備了異步、事件編程的特性[10]. 在處理二進制數據流時,常用的有stream 合并與buffer 合并兩種方式. Node.js 中使用buffer 庫實現原始數據的存儲方法,數據被保存在buffer 的實例中. Node.js 中的stream流是處理流式數據的抽象接口,在處理較大數據量的文件時,采用stream 合并比buffer 合并更有優勢. Buffer需要一次性將數據全部放入內存,如果數據流較大容易導致速度慢,內存爆滿. 流模式合并數據則是一邊讀取數據一邊進行操作,在空間上只占用當前處理數據區域的內存大小,有效地降低了內存的開銷[11]. 同時,對于傳輸過程中的加密及壓縮處理,stream 流具有更高的擴展性. 因此,本文選擇流合并,使用Node.js 的可讀流與可寫流,實現讀取和寫入同步,提高合并效率.

2.2 HTML5 file system

在HTML5 中提供了一種通過File API 規范與本地文件進行交互的標準方法,它的主要作用是將本地文件以文件對象的形式提供給 Web 應用程序進行訪問,為瀏覽器端應用程序的開發提供了無限可能[12].File API 提供了前端處理本地文件的能力,讓圖片預覽、分塊上傳、拖拽上傳等操作變為可能. 以下是本文所用到的對象簡介.

(1)FileList 是一個由File 對象組成的類數組對象.

(2)File 是FileList 中的一個對象,包含文件名稱(name)、大小(size)、類別(type)、修改時間(lastModified-Date)等基本信息.

(3)FileReader 用來讀取文件的API,將文件讀取到內存中,提供將文件讀取為文本、base64 圖片編碼、Buffer 數據類型、二進制字符串等方法,可以實現預覽圖片、計算MD5 等等操作.

(4)Blob 是一個二進制數據,File 對象就繼承自Blob 對象. 通過slice 方法,可以使二進制數據按照字節分塊,返回的對象中包含了源 Blob 對象中指定范圍內的數據[13].

2.3 Spark-md5

對分片文件的標識也是整個文件處理過程中必不可少的一部分. 異步提交的數據中必須包含文件的唯一標識來確認文件分片的順序,驗證是否上傳完畢[14].MD5 生成的hash 碼不可逆,可以作為文件上傳的有效標識,這也是實現文件秒傳的基礎. Spark-md5 是基于Javascript 的前端類庫,它基于文件的內容生成相應hash 值,利用File API 對文件進行分塊之后再進行MD5計算,與傳統的MD5 計算相比,它的傳輸效率很高,不容易引起瀏覽器卡頓、崩潰等問題.

2.4 Web worker

Node.js 和JavaScript 都是單線程編程模型,HTML5的新特性Web worker 為瀏覽器實現多線程操作提供了支持. 在文件上傳過程中,多線程操作顯然比單線程更具有優勢,且不容易造成阻塞. Web worker 允許在Web 程序中并發執行多個JavaScript 腳本,每個腳本執行過程都作為一個線程,各個線程之間彼此獨立,由JavaScript 引擎負責管理[15]. 線程一旦被創建,可以在主線程調用worker 線程,通過將消息發布到代碼指定的事件處理程序.

3 設計與實現

3.1 整體設計

基于對大文件上傳常用方法與關鍵技術的研究,本文設計并實現了完整的前后端大文件上傳系統. 該系統基于HTTP 協議,利用HTML5 的File API 對需要上傳的目標大文件進行分片處理. 同時,充分發揮CPU多核的性能,創建Web worker 線程計算和處理分片的文件,避免主線程阻塞. 通過對分片文件的MD5 校驗及標記,增加文件傳輸的安全性. 在此基礎上,通過自適應分片結合多并發上傳進行優化,提高了傳輸速率.在服務端,服務器接收前端傳輸的分片文件,按分片順序依次存儲,當收到前端的合并請求,服務端使用流模式將收到的所有文件切片進行合并. 此外,在上傳過的切片列表中進行查詢比對,對已經上傳過的相同文件無需再傳,避免重復上傳. 整個系統的流程示意圖如圖1 所示.

圖1 系統流程圖

3.2 前端實現

3.2.1 Hash 計算

為了使服務端對已上傳的內容進行識別,必須要生成文件和切片的 hash 作為校驗. 這里使用Web worker 為JavaScript 創造多線程環境,調用Worker()構造函數,新建一個名為hash 的worker 線程. 在主線程調用worker 線程,通過postMessage()函數傳入文件內容切片后得到的數組fileChunkList,worker 線程利用 FileReader 讀取每個切片的 ArrayBuffer 并不斷傳入Spark-md5 中,每計算完一個切片通過 postMessage 向主線程發送一個進度事件. 主線程通過onMessage函數監聽子線程消息,待全部文件讀取完成后,子線程將最終的 hash 發送給主線程. 整個流程如圖2 所示.

圖2 Web worker 示意圖

3.2.2 自適應分片

在實際的應用場景中,所需要上傳的文件大小往往是不固定的,而分塊大小對文件傳輸有較大影響[16].因此,目前常用的設置固定大小的分片方法不具有靈活性. 自適應分片算法的核心在于,根據上傳文件時的網絡狀況,實現切片大小的動態調整. 在當前切片文件上傳完成時,通過獲取當前切片文件所用上傳時間來調整下一個切片文件的大小,目的是為了每次上傳時切片大小與當前網速相匹配,具有更好的傳輸效率[17].參考TCP 協議的慢啟動策略思想,從分片的小容量文件傳輸開始試探網絡狀況,根據實際測得結果動態調整下一次分片的大小[18]. 比如,如果理想的狀態下每20 s 上傳一個文件塊,其初始文件大小為1 MB,實際計算的上傳時間僅為10 s,那么可以動態的調整下一個分片的大小為2 MB. 另一種可能是實際上傳所用時間為40 s,那么說明當前網絡狀況不足以傳輸1 MB 文件,下一個文件的分片大小可以改為初始值的一半. 因而,在自適應分片算法的計算方法中,設置一個初始切片文件大小為fileChunk,設置理想的上傳單個分片所需時間為ts,實際上傳過程中每個切片所用時間為t,那么當前切片的上傳速率rate可以表示為t/ts. 此時下一切片的文件大小newFileChunk的計算方式為:

本文參照文獻[4] 的參數,設置初始文件大小設為1 MB,理想的參照上傳時間ts為2 s,實際上傳中所用時間t通過new Date().getTime()獲取上傳請求前后的時間戳,得到當前切片上傳時間. 利用式(1)不斷計算得到新的下一切片大小,達到切片大小動態調整的效果.

切片調整部分關鍵代碼摘錄如下:

3.2.3 多并發上傳

為充分利用網絡帶寬,采用多并發的方式進行文件上傳. 并發上傳的并發數受瀏覽器支持的最大并發數限制,超過這個值,執行過程中的并發請求需要等待.文獻[7]中采用固定分片大小結合多并發上傳,研究得到在雙核處理器條件下,并發數為3 時上傳文件的耗時出現拐點,也即上傳時間出現明顯的減少. 本文設置max為最大并發數,通過while 循環執行并發請求,設置counter計數,當max>0 并且當前計數值小于請求長度時進入循環體. 進入執行循環max值減少1,每次傳輸完成,釋放并發通道,以此保證并發數在設定值. 通過對max取值3 到6 進行分別測試,得到上傳耗時在max取值為5 時出現明顯減少. 以此為基礎結合自適應分片,在代碼實現中設置并發數為5,使得文件的分片大小每5 片為一組進行自適應大小的變化,實際耗時t通過5 個切片文件的上傳總耗時求平均得到. 通過這樣的改進方法,得到更短的上傳耗時.

多并發上傳結合自適應分片算法的流程示意圖如圖3 所示.

圖3 流程示意圖

3.3 服務端實現

3.3.1 接收切片文件

對前端傳遞的FormData,服務端使用multiparty包進行處理,創建target 文件夾作為文件上傳的存儲目錄. 前端在發送每個切片時都攜帶了唯一標識hash,服務端將處理后的分片對象從臨時路徑移動到切片文件夾中.

3.3.2 合并切片

服務端接收到來自前端的合并請求后,對切片所在文件夾下的所有切片進行合并. 首先采用sort()方法根據切片的下標進行排序,避免從目錄讀取的文件順序發生錯亂[19]. 使用 fs.createWriteStream 生成可寫流,通過fs.createReadStream 生成可讀流,將切片文件夾內的切片傳輸到目標文件夾中并合并. createWriteStream方法的兩個參數控制可讀流傳輸到可寫流指定的位置.這樣做能保證在并發合并多個可讀流時,不必按照流的順序一個接一個傳輸也能使切片傳輸到正確的位置[20]. 與確定上一個寫入完成再讀取下一個流的方式相比,多并發上傳大大提高了傳輸效率.

3.3.3 文件秒傳

文件hash 值與文件后綴作為目錄,使用fse.exists-Sync 檢測文件目錄是否存在,如果存在,則將標志位置為false,不需要再次上傳. 如果不存在,則將標志位置為true. 在此基礎上,文件秒傳的實現只需要在用戶選擇上傳已存在的相同資源時,直接提示上傳成功. 在前文服務端驗證hash 的基礎上,如果發現hash 相同的文件,說明該文件資源已經上傳,可以直接返回上傳成功.

4 實驗分析

本文使用文獻[7]中的設計方法作為對照,將固定分片上傳與自適應分片上傳的方法進行對比. 選取了3 個100 MB 以上不同大小的文件進行測試,文獻[7]所用方法測得的時間記做原始方法用時,本文提出的方法記做改進方法. 原始方法采用固定分片大小2 MB,同時選擇并發數為5 進行多并發上傳; 改進方法選擇相同的并發數,采用改進的自適應分片算法,以2 MB大小為起始分片大小進行上傳. 瀏覽器選擇Chrome,通過控制臺的網絡network 面板查看分片的請求狀態以及實驗結果. 在同樣的網絡環境下,每個文件采用兩種上傳方式分別進行3 次測試,統計其平均值作為對照,測試結果如表1 所示.

在文件上傳的測試過程中,針對同一文件,再次上傳時,經過對MD5 碼的校驗,可以直接實現秒傳,系統彈窗提示上傳成功. 表1 中傳輸時間的計算是從開始上傳到服務端接口合并完成文件的整個過程. 由表1可以看出,本系統可以支持500 MB 以上大文件的上傳,不同大小的文件上傳所用時間改進方法均少于原始方法耗時,并且隨著源文件大小的增大更大時比固定分片上傳具有更明顯的上傳時間優勢. 通過后端流合并的方式對分片文件進行合并,得到的上傳文件與源文件一致,MD5 值的唯一標識也保證了文件秒傳的實現,避免對同一文件的重復上傳,節約了時間成本.

表1 實驗結果(s)

5 結論

本文研究并介紹了常用的大文件上傳方法以及存在的問題,對本系統所用到的關鍵技術Node.js 及File API 進行了闡述,通過對前后端上傳過程的具體研究,實現了基于Node.js 的大文件上傳系統,通過對多并發上傳與自適應切片相結合的算法,實現了更具有靈活性和更高傳輸效率的大文件上傳. 同時針對大文件的MD5 標識計算,利用Web worker 多線程計算的方式有效地避免主線程的卡頓. 該系統靈活度高,適用性強,能夠在文件上傳過程中提高上傳效率,提升用戶體驗.

猜你喜歡
方法
中醫特有的急救方法
中老年保健(2021年9期)2021-08-24 03:52:04
高中數學教學改革的方法
河北畫報(2021年2期)2021-05-25 02:07:46
化學反應多變幻 “虛擬”方法幫大忙
變快的方法
兒童繪本(2020年5期)2020-04-07 17:46:30
學習方法
用對方法才能瘦
Coco薇(2016年2期)2016-03-22 02:42:52
最有效的簡單方法
山東青年(2016年1期)2016-02-28 14:25:23
四大方法 教你不再“坐以待病”!
Coco薇(2015年1期)2015-08-13 02:47:34
賺錢方法
捕魚
主站蜘蛛池模板: 色婷婷在线影院| 国产大片喷水在线在线视频| 天天色综网| 97国产一区二区精品久久呦| 亚洲无码高清免费视频亚洲| 99视频在线免费| 亚洲乱码精品久久久久..| 午夜丁香婷婷| 99精品视频在线观看免费播放| 六月婷婷激情综合| 91国内视频在线观看| 国产九九精品视频| 97影院午夜在线观看视频| 色婷婷成人网| 国产精品成人久久| 91麻豆国产在线| 免费人成网站在线观看欧美| 91精品专区国产盗摄| 丰满少妇αⅴ无码区| 成人午夜视频免费看欧美| 玖玖精品视频在线观看| 亚洲va视频| 亚洲欧美国产视频| 欧美一区二区精品久久久| 永久免费无码日韩视频| 久久黄色一级视频| 国产制服丝袜无码视频| 天天综合网色中文字幕| 国产毛片高清一级国语| 日韩欧美国产中文| av大片在线无码免费| 四虎综合网| 亚洲色图综合在线| 国产十八禁在线观看免费| 国产在线日本| 亚洲天堂啪啪| 五月综合色婷婷| 亚洲综合第一区| 国产男女免费视频| 九色免费视频| 亚洲精品天堂在线观看| 亚洲 欧美 偷自乱 图片| 免费Aⅴ片在线观看蜜芽Tⅴ| 成·人免费午夜无码视频在线观看| 日韩高清中文字幕| 亚洲AⅤ综合在线欧美一区| 亚洲码一区二区三区| 国内精品视频| 亚洲国产精品美女| 在线毛片免费| 国产欧美在线观看一区 | 香蕉eeww99国产在线观看| 成人午夜久久| 黑人巨大精品欧美一区二区区| 色视频国产| 国产精品太粉嫩高中在线观看 | 无码精品一区二区久久久| 四虎精品黑人视频| 99福利视频导航| 婷婷色一二三区波多野衣 | 久久青草热| 激情无码视频在线看| 2021国产精品自产拍在线观看 | 日本爱爱精品一区二区| 亚洲激情区| 欧美人与动牲交a欧美精品| 亚洲男人的天堂视频| 欧美日韩国产在线观看一区二区三区| 国产毛片片精品天天看视频| 看看一级毛片| 国产一二三区视频| 狠狠操夜夜爽| 欧美在线综合视频| 视频二区中文无码| 国产精品视频公开费视频| 亚洲va视频| 亚洲性影院| 久久久久人妻一区精品色奶水| 韩国福利一区| 欧美a在线看| 波多野结衣爽到高潮漏水大喷| 欧美成人在线免费|