chunkupload簡介 chunkupload是一款基於java語言的斷點續傳組件,針對文件上傳,非文件下載,集成方便,使用簡單。 從整體上講,chunkupload會對文件進行切片處理,每個切片4M大小,預設情況下,chunkupload不會對切片進行合併,筆者也不建議在上傳文件時對切片進行合 ...
chunkupload簡介
chunkupload是一款基於java語言的斷點續傳組件,針對文件上傳,非文件下載,集成方便,使用簡單。
從整體上講,chunkupload會對文件進行切片處理,每個切片4M大小,預設情況下,chunkupload不會對切片進行合併,筆者也不建議在上傳文件時對切片進行合併,雖然chunkupload支持這項操作。
對於客戶端(瀏覽器)而言,chunkupload組件會在客戶端計算文件MD5,為了儘可能提高計算效率,chunkupload在客戶端腳本中使用了web worker,因此,客戶端相容性會受到較為嚴重的影響。
對於服務端而言,通過文件MD5+文件大小,唯一確定一個文件,並且基於文件MD5前6位,每兩位作為一級目錄,自動生成分散的目錄結構,假如文件MD5為[071287fffa974b878732a7a17858be36],那麼生成的目錄結構如下:[自定義的rootpath] + [/07/12/87/] +[文件MD5+文件長度]。文件目錄下的文件結構如下圖:
其中,文件信息中包含:文件狀態(是否上傳完成)、文件MD5、文件大小、切片數量、每一個切片的序號+MD5信息。
目前chunkupload通過servlet實現與瀏覽器的交互,完成了基於瀏覽器的斷點續傳,實際上,使用者完全可以調用chunkupload核心類庫自行操作文件,比如切片合併操作。
總的來說,chunkupload具有如下特性:
· 實現斷點續傳。
· 對於同一個文件,允許多用戶上傳,並且上傳的用戶越多,上傳越快。
· 線程安全。
· 進程安全(同一物理機,非集群環境)。
由於chunkupload目前還處於測試階段,過多的技術細節,筆者說多了也是白費,為了不做井底之蛙,公佈chunkupload有如下幾個期望:
· 確定當前的模式是否符合大眾需求。
· 確定是否有可能用於生產環境。
· 確定是否存在潛在的不可行因素。
· 積極改進chunkupload。
總之,希望大家能給我一些建議,筆者水平有限,希望chunkupload最終能成為一個優秀的開源項目。
感受一下chunkupload使用方法
服務端
引用chunkupload.jar包,chunkupload.jar無任何第三方依賴。
在項目web.xml中配置chunkupload servlet。
1 <servlet> 2 <servlet-name>ChunkUpload</servlet-name> 3 <servlet-class>com.iyangyuan.chunkupload.servlet.DispatcherServlet</servlet-class> 4 </servlet> 5 <servlet-mapping> 6 <servlet-name>ChunkUpload</servlet-name> 7 <url-pattern>/chunkupload/*</url-pattern> 8 </servlet-mapping>
客戶端(瀏覽器)
引用dawn.js,用於計算文件MD5,dawn.js算是chunkupload的一個附屬項目。
引用chunkupload.js,用於與服務端進行交互,chunkupload.js核心思想是只關註交互,不關註具體UI展現,因為各個產品UI不盡相同,chunkupload.js不對UI做過多限制、干擾。
無任何第三方依賴。
1 <html> 2 <head> 3 <title>ChunkUpload 文件上傳示例</title> 4 <meta charset="utf-8"> 5 <meta name="viewport" id="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0"> 6 <style> 7 body{ 8 font-family: "Source Sans Pro", "Helvetica Neue", Helvetica, Arial, sans-serif; 9 } 10 body > div { 11 width: 200px; 12 margin: 20px auto 0 auto; 13 } 14 body > div.form { 15 text-align: center; 16 } 17 body > div.form > input { 18 margin-top: 12px; 19 border: 1px dashed #dcdcdc; 20 padding: 4px 8px; 21 cursor: pointer; 22 background-color: transparent; 23 color: #686868; 24 font-family: inherit; 25 outline: none; 26 } 27 body > div.form > input.button { 28 font-size: 15px; 29 line-height: 29px; 30 padding: 0 10px; 31 } 32 body > div.form > input:hover { 33 background-color: #f5f5f5; 34 } 35 div.info > div{ 36 margin: auto; 37 height: 31px; 38 width: 88px; 39 background: url('data:image/gif;base64,R0lGODlhWAAfAMMBAAAAAP////XcoPDLdfTboP+dzv+z2f+AwP9brfPZoAAAAAAAAAAAAAAAAAAAAAAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQFFAAKACwAAAAAWAAfAAAE/xDISau9OOvNd/hgKI5kaZ5oWkqB4L5wLM90bd+4PLB57//A2g7QChqPyNiwmGw6c8undKrj/STULC3qAxQAMKw0IUiYyy6yWf3j5rwGsMsrd5JfdzQelre5bxIFcROCdUBneWx6aHd9UFY1hAaTAJQTRo6LfYl8i0KQMoGCk6Slg0FsnGmdq3uZSpBiAnCmtaWGqK4yiq2eVURzwbS2pBK3hzabezOvLlxyYMPEg5aXWk1uWNLTxaOU10lR2oHckwcHlIWn4Ed/c97ECOfocJWy7EDus/C28udx8HAlaZYP1ItttRAgKEYBGS9NelL10LevnC2BR1RhM3iwAD9uGE5/NBvpg+IcLx5BhvTxiiDBGSYPivJI0xo+JzHfZfjyxNHDGC9/MaFhb0bRmzg5hoqE9EnOpk2XDJhKtarVq1izat3KtSvWDmDDih0LNgIAIfkEBRQACgAsAwAGADEAFgAABJ9QyEmrBMDqzbsFRTZh3pacZQUaogC2qZRQc4oVLLbCaS2XOpyBNdTxYjPf5iYcOp+kmCfqaj6vUClHlFlhr5is9nOpfsGAonGs6lrPUOvR1r3BnYdDEZemskdvWAh5ejs5fyqBV4N5LHKIiXcGCAhORnMmAkoUXpJgkEsFimeYPVsgond+oEtMoq86rJpTIZdBpbIjLBp9spu8W7nCshEAIfkEBRQACgAsAwAFADoAFgAABLdQyEmrAMDqzWXySdhZQJFN2KhS30oWxnmZrtp++IrB2B7XNmAPZogVezKgJidobXbEonSaUjaZE2erOpt6vz+gk5VFSTIlsBdDFTffnRM6qo4Bjkirbl4Hp6VJHTdxaD59BgcHRzx2ei5/dQiJiml3XI5xdGCSiTF0gZhPml8ICIB5oSqQh22pjwWjdaAuOWNjJCWwfZeuWoS5sME9rh4VtxolSMo0vXqWyGHESyOzZ9LHx9LaAhEAIfkEBRQACgAsAgAFAEQAFgAABMtQyEmrvTjrmmT63VYBgGieVIhSQFFO5CpPYWefrfEK7T5fto+g9iMVdKSc75dqOlWZ5NGgoyaXK6HqNvR4vxbjlEoux2ZQcHrL2uXK8DhWdGODo5LSO24GmJlqXSIvemN8Vn5ISVkaaRgxe4dwkXOAGpBGkmQHB1ZHfmeWRYZ8CJydSkiiTJGlpzqGlauDpHEICGRXsrMbrZq5THVPXcJhBbWSu2g0MmLIucona4BSx9YuoaKOzBbbMNi6RtHaRToXoLyO3nfneLw/EQAh+QQFFAAKACwCAAUASwAXAAAE3lDISau9OOtdE/9gKI4aAJDo5qUSUJyTyVJeYgtrfeesa8ACF5C1khSLuEkNZSr8TL4haKdMWpM8o/YDdRp+X6iUg9xer2VR0/ttu2Wh5bFKP5eAPrd+P55W00t2FjAneXtvAG9xGkhzHIRBbIdhiU9QM5gxhZKTb5J9mSAyXZ1tBwdhTolwoZiGkwinqFFPrZmvh7GnP5+haTSinHsICG1ioBdywFo8WRu4pcaZjslqBcKdyGQYv2ZcLtelrCS/3YKia9fql7btgy/HXdofZYHVTD8Xq+78FMjz/TBEAAA7') no-repeat center center; 40 padding: 2px; 41 box-sizing: border-box; 42 } 43 div.info > div > p{ 44 text-align: right; 45 font-size: 12px; 46 margin: 0; 47 } 48 </style> 49 </head> 50 <body> 51 <!-- 表單部分 --> 52 <div class="form"> 53 <input id="bigFile" type="file" placeholder="選擇一個文件" /> 54 <input id="execBtn" class="button" type="button" value="上傳" /> 55 </div> 56 <!-- 上傳進度展示 --> 57 <div class="info"> 58 <div> 59 <!-- 提示文本 --> 60 <p id="text"></p> 61 <!-- 執行進度 --> 62 <p id="progress"></p> 63 </div> 64 </div> 65 </body> 66 <script src="/static/lib/dawn/dawn.js"></script> 67 <script src="/static/lib/chunkupload/chunkupload.js"></script> 68 <script> 69 var fileInput = document.getElementById("bigFile"), 70 execBtn = document.getElementById("execBtn"), 71 text = document.getElementById("text"), 72 progress = document.getElementById("progress"); 73 74 execBtn.addEventListener("click", function(e) { 75 var file, cu; 76 file = fileInput.files[0]; 77 cu = new ChunkUpload(file); 78 cu.upload({ 79 "success": function(block){ 80 /** 81 * 上傳成功後,會返回一個block對象 82 * 通過block對象,可以在一定程度上管理文件,目前支持: 83 * 獲取文件信息(參見info_example.html) 84 * 刪除文件(參見delete_example.html) 85 */ 86 text.innerText = "上傳完成"; 87 }, 88 "error": function(e){ 89 text.innerText = e; 90 progress.innerText = ""; 91 }, 92 "md5Progress": function(n){ 93 text.innerText = "計算MD5"; 94 progress.innerText = n + "%"; 95 }, 96 "uploadProgress": function(n){ 97 text.innerText = "正在上傳"; 98 progress.innerText = n + "%"; 99 } 100 }); 101 }); 102 </script> 103 </html>
通過以下四個回調,與UI進行交互,完成文件上傳。
·success上傳成功回調
·error 異常回調
·md5Progress MD5計算進度回調
·uploadProgress 上傳進度回調
目前項目基本完成,註釋詳盡,發佈指日可待~