日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

Java實(shí)現(xiàn)瀏覽器端大文件分片上傳

瀏覽:33日期:2023-02-14 10:01:43
目錄背景介紹項(xiàng)目介紹需要知識(shí)點(diǎn)啟動(dòng)項(xiàng)目項(xiàng)目示范核心講解核心原理功能分析分塊上傳秒傳功能斷點(diǎn)續(xù)傳總結(jié)參考文獻(xiàn)背景介紹

  Breakpoint-http,是不是覺得這個(gè)名字有點(diǎn)low,break point斷點(diǎn)。這是一個(gè)大文件上傳的一種實(shí)現(xiàn)。因?yàn)楸緛砗芫脹]寫過前端了,本來想自己好好寫一番js,可惜因?yàn)榉N種原因而作罷了。該項(xiàng)目是基于一款百度開源的前端上傳控件:WebUploader(百度開源的東西文檔一如既往的差,哈哈。或者是我理解能力差)。

  Breakpoint-http,當(dāng)初想實(shí)現(xiàn)這一塊web大文件上傳,是因?yàn)橛幸惶焱瑫r(shí)詢問我這方面的知識(shí),我發(fā)現(xiàn)好像在實(shí)戰(zhàn)中沒寫過這類的代碼啊。既然知道了自己不足那肯定要狠狠補(bǔ)一下。所以才有了這個(gè)項(xiàng)目。

  對(duì)了這個(gè)項(xiàng)目是gradle+Spring Boot可能有部分人還沒接觸過這兩個(gè)東西,這里就不進(jìn)行講解了,畢竟這不是重點(diǎn),把gradle當(dāng)成maven吧,雖然它還有更出色的功能。Spring Boot用來簡(jiǎn)化Spring應(yīng)用的初始搭建以及開發(fā)過程,一個(gè)約定大于規(guī)范的框架。

項(xiàng)目介紹

  Breakpoint-http 是一個(gè)基于大文件上傳,并參考網(wǎng)盤上傳文件,而基于web的大文件上傳實(shí)現(xiàn)項(xiàng)目。web中上傳大文件沒有桌面軟件那么容易,還好現(xiàn)在是身處于一個(gè)html5的時(shí)代。我們web端上傳文件常用的做法就是用表單上傳了,一旦上傳的文件大小較大,一旦帶寬跟不上,那用戶只能在哪里一直等著,不能做刷新頁面的操作,并且一旦產(chǎn)生網(wǎng)絡(luò)波動(dòng),那么用戶所做的一切就白費(fèi)了。  Breakpoint-http就是為了保證在web端上傳大文件能達(dá)到基本的可靠性的一種方案,方法多種,可能的方案會(huì)更出色,歡迎討論。要讓大文件上傳能達(dá)到可用性,我們需要做到怎么樣的程度呢?  * 斷點(diǎn)續(xù)傳 最主要的功能之一,在斷網(wǎng)或者在暫停的情況下,能夠在上傳斷點(diǎn)中繼續(xù)上傳。  * 分塊上傳 也是斷點(diǎn)續(xù)傳的基礎(chǔ)之一,把大文件通過前端分塊,然后后臺(tái)在組在一起。  * 文件妙傳 這個(gè)相信大家在網(wǎng)盤中見過不少了,就是服務(wù)中已經(jīng)有人上傳過得文件,其他人再上傳這個(gè)文件就秒上傳到服務(wù)中去。  * 其他功能 把下面這些功能歸類到其他,是因?yàn)樗鼈兓径际峭ㄟ^WebUploader(http://fex.baidu.com/webuploader)來實(shí)現(xiàn)的,很簡(jiǎn)單。   - 多線程上傳 多個(gè)線程上傳不同的塊文件。   - 文件進(jìn)度顯示 顯示文件的上傳完成情況。   - UI等等。

需要知識(shí)點(diǎn) 基于spring boot開發(fā)的。 WebUploader,WebUploader是由Baidu WebFE(FEX)團(tuán)隊(duì)開發(fā)的一個(gè)簡(jiǎn)單的以HTML5為主,F(xiàn)LASH為輔的現(xiàn)代文件上傳組件。 redis,key-value存儲(chǔ)系統(tǒng),在這里我把redis用作存儲(chǔ)文件路徑來使用。 Gradle,Gradle是一個(gè)基于JVM的構(gòu)建工具。這里我用Gradle頂替了Maven。嗯,多學(xué)點(diǎn)東西。啟動(dòng)項(xiàng)目

main方法直接運(yùn)行:(1)找到App啟動(dòng)類(win.pangniu.learn包下)(2)執(zhí)行main方法。(3)然后用瀏覽器訪問:http://localhost:9090

tomcat運(yùn)行:(1)執(zhí)行命令gradle war。(2)在out目錄下找到bphttp.war包。(3)拷貝到tomcat,然后運(yùn)行tomcat。(4)然后用瀏覽器訪問:http://localhost:9090

項(xiàng)目示范

上傳完后的頁面

Java實(shí)現(xiàn)瀏覽器端大文件分片上傳

妙傳功能演示頁面

Java實(shí)現(xiàn)瀏覽器端大文件分片上傳

核心講解核心原理

該項(xiàng)目核心就是文件分塊上傳。前后端要高度配合,需要雙方約定好一些數(shù)據(jù),才能完成大文件分塊,我們?cè)陧?xiàng)目中要重點(diǎn)解決的以下問題。* 如何分片;* 如何合成一個(gè)文件;* 中斷了從哪個(gè)分片開始。如何分,利用強(qiáng)大的js庫,來減輕我們的工作,市場(chǎng)上已經(jīng)能有關(guān)于大文件分塊的輪子,雖然程序員的天性曾迫使我重新造輪子。但是因?yàn)闀r(shí)間的關(guān)系還有工作的關(guān)系,我只能罷休了。最后我選擇了百度的WebUploader來實(shí)現(xiàn)前端所需。如何合,在合之前,我們還得先解決一個(gè)問題,我們?nèi)绾螀^(qū)分分塊所屬那個(gè)文件的。剛開始的時(shí)候,我是采用了前端生成了唯一uuid來做文件的標(biāo)志,在每個(gè)分片請(qǐng)求上帶上。不過后來在做秒傳的時(shí)候我放棄了,采用了Md5來維護(hù)分塊和文件關(guān)系。在服務(wù)端合并文件,和記錄分塊的問題,在這方面其實(shí)行業(yè)已經(jīng)給了很好的解決方案了。參考迅雷,你會(huì)發(fā)現(xiàn),每次下載中的時(shí)候,都會(huì)有兩個(gè)文件,一個(gè)文件主體,另外一個(gè)就是文件臨時(shí)文件,臨時(shí)文件存儲(chǔ)著每個(gè)分塊對(duì)應(yīng)字節(jié)位的狀態(tài)。這些都是需要前后端密切聯(lián)系才能做好,前端需要根據(jù)固定大小對(duì)文件進(jìn)行分片,并且請(qǐng)求中要帶上分片序號(hào)和大小。前端發(fā)送請(qǐng)求順利到達(dá)后臺(tái)后,服務(wù)器只需要按照請(qǐng)求數(shù)據(jù)中給的分片序號(hào)和每片分塊大小(分片大小是固定且一樣的)算出開始位置,與讀取到的文件片段數(shù)據(jù),寫入文件即可。

功能分析分塊上傳

分塊上傳可以說是我們整個(gè)項(xiàng)目的基礎(chǔ),像斷點(diǎn)續(xù)傳、暫停這些都是需要用到分塊。分塊這塊相對(duì)來說比較簡(jiǎn)單。前端是采用了webuploader,分塊等基礎(chǔ)功能已經(jīng)封裝起來,使用方便。借助webUpload提供給我們的文件API,前端就顯得異常簡(jiǎn)單。

// 實(shí)例化wu var uploader = WebUploader.create({pick: { id: ’#picker’, label: ’點(diǎn)擊選擇文件’},formData: { uid: 0, md5: ’’, chunkSize: chunkSize},//dnd: ’#dndArea’,//paste: ’#uploader’,swf: ’js/Uploader.swf’,chunked: true,chunkSize: chunkSize, // 字節(jié) 1M分塊threads: 3,server: ’index/fileUpload’,auto: false,// 禁掉全局的拖拽功能。這樣不會(huì)出現(xiàn)圖片拖進(jìn)頁面的時(shí)候,把圖片打開。disableGlobalDnd: true,fileNumLimit: 1024,fileSizeLimit: 1024 * 1024 * 1024, // 200 MfileSingleSizeLimit: 1024 * 1024 * 1024 // 50 M });

分則必合。把大文件分片了,但是分片了就沒有原本文件功能,所以我們要把分片合成為原本的文件。我們只需要把分片按原本位置寫入到文件中去。因?yàn)榍懊嬖砟且徊课覀円呀?jīng)講到了,我們知道分塊大小和分塊序號(hào),我就可以知道該分塊在文件中的起始位置。所以這里使用RandomAccessFile是明智的,RandomAccessFile能在文件里面前后移動(dòng)。但是在andomAccessFile的絕大多數(shù)功能,已經(jīng)被JDK1.4的NIO的“內(nèi)存映射文件(memory-mapped files)”取代了。我在該項(xiàng)目中分別寫了使用RandomAccessFile與MappedByteBuffer來合成文件。分別對(duì)應(yīng)的方法是uploadFileRandomAccessFile和uploadFileByMappedByteBuffer。兩個(gè)方法代碼如下。

public void uploadFileRandomAccessFile(MultipartFileParam param) throws IOException {String fileName = param.getName();String tempDirPath = finalDirPath + param.getMd5();String tempFileName = fileName + '_tmp';File tmpDir = new File(tempDirPath);File tmpFile = new File(tempDirPath, tempFileName);if (!tmpDir.exists()) { tmpDir.mkdirs();}RandomAccessFile accessTmpFile = new RandomAccessFile(tmpFile, 'rw');long offset = CHUNK_SIZE * param.getChunk();//定位到該分片的偏移量accessTmpFile.seek(offset);//寫入該分片數(shù)據(jù)accessTmpFile.write(param.getFile().getBytes());// 釋放accessTmpFile.close();boolean isOk = checkAndSetUploadProgress(param, tempDirPath);if (isOk) { boolean flag = renameFile(tmpFile, fileName); System.out.println('upload complete !!' + flag + ' name=' + fileName);} } public void uploadFileByMappedByteBuffer(MultipartFileParam param) throws IOException { String fileName = param.getName(); String uploadDirPath = finalDirPath + param.getMd5(); String tempFileName = fileName + '_tmp'; File tmpDir = new File(uploadDirPath); File tmpFile = new File(uploadDirPath, tempFileName); if (!tmpDir.exists()) {tmpDir.mkdirs(); } RandomAccessFile tempRaf = new RandomAccessFile(tmpFile, 'rw'); FileChannel fileChannel = tempRaf.getChannel(); //寫入該分片數(shù)據(jù) long offset = CHUNK_SIZE * param.getChunk(); byte[] fileData = param.getFile().getBytes(); MappedByteBuffer mappedByteBuffer = fileChannel.map(FileChannel.MapMode.READ_WRITE, offset, fileData.length); mappedByteBuffer.put(fileData); // 釋放 FileMD5Util.freedMappedByteBuffer(mappedByteBuffer); fileChannel.close(); boolean isOk = checkAndSetUploadProgress(param, uploadDirPath); if (isOk) {boolean flag = renameFile(tmpFile, fileName);System.out.println('upload complete !!' + flag + ' name=' + fileName); }}秒傳功能

秒傳功能,相信大家都體現(xiàn)過了,網(wǎng)盤上傳的時(shí)候,發(fā)現(xiàn)上傳的文件秒傳了。其實(shí)原理稍微有研究過的同學(xué)應(yīng)該知道,其實(shí)就是檢驗(yàn)文件MD5,記錄下上傳到系統(tǒng)的文件的MD5,在一個(gè)文件上傳前先獲取文件內(nèi)容MD5值或者部分取值MD5,然后在匹配系統(tǒng)上的數(shù)據(jù)。Breakpoint-http實(shí)現(xiàn)秒傳原理,客戶端選擇文件之后,點(diǎn)擊上傳的時(shí)候觸發(fā)獲取文件MD5值,獲取MD5后調(diào)用系統(tǒng)一個(gè)接口(/index/checkFileMd5),查詢?cè)揗D5是否已經(jīng)存在(我在該項(xiàng)目中用redis來存儲(chǔ)數(shù)據(jù),用文件MD5值來作key,value是文件存儲(chǔ)的地址。)接口返回檢查狀態(tài),然后再進(jìn)行下一步的操作。相信大家看代碼就能明白了。 嗯,前端的MD5取值也是用了webuploader自帶的功能,這還是個(gè)不錯(cuò)的工具。

斷點(diǎn)續(xù)傳

斷點(diǎn)續(xù)傳,就是在文件上傳的過程中發(fā)生了中斷,人為因素(暫停)或者不可抗力(斷網(wǎng)或者網(wǎng)絡(luò)差)導(dǎo)致了文件上傳到一半失敗了。然后在環(huán)境恢復(fù)的時(shí)候,重新上傳該文件,而不至于是從新開始上傳的。 前面也已經(jīng)講過,斷點(diǎn)續(xù)傳的功能是基于分塊上傳來實(shí)現(xiàn)的,把一個(gè)大文件分成很多個(gè)小塊,服務(wù)端能夠把每個(gè)上傳成功的分塊都落地下來,客戶端在上傳文件開始時(shí)調(diào)用接口快速驗(yàn)證,條件選擇跳過某個(gè)分塊。 實(shí)現(xiàn)原理,就是在每個(gè)文件上傳前,就獲取到文件MD5取值,在上傳文件前調(diào)用接口(/index/checkFileMd5,沒錯(cuò)也是秒傳的檢驗(yàn)接口)如果獲取的文件狀態(tài)是未完成,則返回所有的還沒上傳的分塊的編號(hào),然后前端進(jìn)行條件篩算出哪些沒上傳的分塊,然后進(jìn)行上傳。

/** * 秒傳判斷,斷點(diǎn)判斷 * * @return */ @RequestMapping(value = 'checkFileMd5', method = RequestMethod.POST) @ResponseBody public Object checkFileMd5(String md5) throws IOException {Object processingObj = stringRedisTemplate.opsForHash().get(Constants.FILE_UPLOAD_STATUS, md5);if (processingObj == null) { return new ResultVo(ResultStatus.NO_HAVE);}String processingStr = processingObj.toString();boolean processing = Boolean.parseBoolean(processingStr);String value = stringRedisTemplate.opsForValue().get(Constants.FILE_MD5_KEY + md5);if (processing) { return new ResultVo(ResultStatus.IS_HAVE, value);} else { File confFile = new File(value); byte[] completeList = FileUtils.readFileToByteArray(confFile); List<String> missChunkList = new LinkedList<>(); for (int i = 0; i < completeList.length; i++) {if (completeList[i] != Byte.MAX_VALUE) { missChunkList.add(i + '');} } return new ResultVo<>(ResultStatus.ING_HAVE, missChunkList);} }總結(jié)

身為一個(gè)具有拖延癥的程序猿,寫個(gè)文檔及其不容易,這方面還是優(yōu)待加強(qiáng),寫代碼時(shí)間都還沒寫這個(gè)文檔長(zhǎng),并且寫了那么久還那么爛的文檔。實(shí)在抱歉,望諒解。

獲取代碼

GitHub:https://github.com/Fourwenwen/Breakpoint-http.gitOSChina項(xiàng)目主頁: https://git.oschina.net/Fourwenwen/breakpoint-http.git

參考文獻(xiàn)

[1]http://fex.baidu.com/webuploader/[2]http://www.zuidaima.com/blog/2819949848316928.htm[3]https://my.oschina.net/feichexia/blog/212318

到此這篇關(guān)于Java實(shí)現(xiàn)瀏覽器端大文件分片上傳的文章就介紹到這了,更多相關(guān)Java 大文件分片上傳內(nèi)容請(qǐng)搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Java
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
久久精品一区二区国产| 一区二区小说| 久久亚洲美女| 久久亚洲欧洲| 欧美一区=区三区| 日韩成人精品一区二区三区| 日韩动漫一区| 国产日韩欧美中文在线| 国产精品99精品一区二区三区∴| 精品伊人久久久| 亚洲风情在线资源| 欧美~级网站不卡| 美女黄网久久| 青青国产精品| 成人国产精选| 精品91久久久久| 日韩精品91亚洲二区在线观看| 国产情侣一区在线| av资源亚洲| 欧美搞黄网站| 视频一区中文字幕精品| 国产乱论精品| 久久久久久久久丰满| 蜜臀av一区二区三区| 国产剧情一区二区在线观看| 日韩欧美一区免费| 午夜一级在线看亚洲| 久久精品72免费观看| 丝袜av一区| 亚洲欧美网站在线观看| 捆绑调教美女网站视频一区 | 日韩在线观看| 视频一区视频二区在线观看| 国产亚洲字幕| 日韩精品免费一区二区三区| 一本综合精品| 欧美日韩国产观看视频| 亚洲日本在线观看视频| 视频在线不卡免费观看| 免费精品视频最新在线| 激情久久99| 日av在线不卡| 国产精品久久久久蜜臀| 麻豆9191精品国产| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 亚洲欧美久久久| 欧美激情网址| 国产一区91| 国产精品99一区二区三| 日韩午夜电影| 精品视频黄色| 日韩国产在线观看| 欧美 日韩 国产精品免费观看| 国产精品久久久网站| 99视频+国产日韩欧美| 成人影视亚洲图片在线| 日本va欧美va欧美va精品| 亚洲国产成人精品女人| 91青青国产在线观看精品| 亚洲网址在线观看| 影视先锋久久| 黄色在线网站噜噜噜| 国产精品亚洲综合久久| 自拍自偷一区二区三区| 欧美日韩在线网站| 国产成人免费精品| 综合一区在线| 91成人精品| 日本一区二区高清不卡| 欧美一区=区三区| 日韩中文字幕91| 亚洲天堂成人| 涩涩av在线| 精品免费在线| 欧美日韩一区自拍| 久久亚洲国产精品一区二区| 在线一区免费| 国产综合婷婷| 欧美日中文字幕| 欧美日韩视频免费观看| 97国产成人高清在线观看| 国产精品观看| 国产精品qvod| 久久精品网址| 久久超级碰碰| 国产精品mm| 老司机免费视频一区二区| 欧美精品91| 国产精品美女午夜爽爽| 日韩一区二区三免费高清在线观看| 亚洲一区国产| 巨乳诱惑日韩免费av| 国产亚洲网站| 国产精品社区| 日韩精品一卡二卡三卡四卡无卡| 欧美日韩视频| 美女国产精品| 亚洲精品黄色| 日韩国产一二三区| 国产亚洲人成a在线v网站| 日韩国产欧美三级| 国产欧美91| 久久麻豆视频| 国产精品伦理久久久久久| 国产精品麻豆久久| 9999国产精品| 日韩毛片在线| 亚洲一区二区三区四区五区午夜 | 蜜臀va亚洲va欧美va天堂| 亚洲专区视频| 日本成人中文字幕在线视频| 国产精品久久久久久久久久久久久久久 | 欧美va天堂| 中文国产一区| 日韩精品久久久久久| 亚洲精选91| 91午夜精品| 欧美激情福利| 成人美女视频| 日韩一区二区久久| 中文无码日韩欧| 国产精品高清一区二区| 桃色一区二区| 国产精品美女久久久浪潮软件| 亚洲精品一级| 另类欧美日韩国产在线| 久久久久久久久99精品大| 水野朝阳av一区二区三区| 日本va欧美va精品| caoporn视频在线| 午夜日本精品| 欧美在线日韩| 久久夜夜操妹子| 一区二区三区四区日韩| 国产精品日本一区二区不卡视频| 麻豆传媒一区二区三区| 亚洲国产成人精品女人| 日韩高清一区在线| 日韩在线短视频| 日韩影片在线观看| 亚洲精品国产嫩草在线观看| 蜜桃一区二区三区在线| 久久99蜜桃| 午夜欧美在线| 免费亚洲婷婷| 天使萌一区二区三区免费观看| 欧美亚洲福利| 久久理论电影| 国产免费av一区二区三区| 日韩精品电影| 中文字幕一区二区三区在线视频| 红杏一区二区三区| 免费成人在线影院| 国产传媒在线观看| 青草久久视频| 99视频在线精品国自产拍免费观看| 国产免费久久| 日韩在线播放一区二区| 亚洲深夜视频| 欧美中文一区| 亚洲免费高清| 色爱综合网欧美| 97精品国产99久久久久久免费| 欧美特黄一级大片| 久久99蜜桃| 先锋影音久久久| 在线人成日本视频| 欧美啪啪一区| 视频精品一区二区| 秋霞影视一区二区三区| 国产精品极品在线观看| 伊人久久大香伊蕉在人线观看热v| 色网在线免费观看| 国产精品2023| 日韩1区2区3区| 亚洲在线观看| 久久青草久久| 久久精品国产一区二区| 日产欧产美韩系列久久99| 黄色成人在线网址| 日韩国产一区| www.九色在线| 久久亚洲资源中文字| 亚洲精品动态| 99国产一区| 欧美日韩国产免费观看| 麻豆精品99| 国产精品极品在线观看| 日本电影久久久| 亚洲理论在线| 亚洲精品综合| 亚洲免费专区| 久久久久午夜电影| 日韩一区二区在线免费| 国产+成+人+亚洲欧洲在线| 青青国产精品| 日韩av中文字幕一区二区三区| 久久性天堂网| 丝袜诱惑制服诱惑色一区在线观看| 亚洲精品一二三区区别|