前言:
WebUploader是由Baidu WebFE(FEX)團隊開發的一個簡單的以HTML5爲主,FLASH爲輔的現代文件上傳組件。在現代的瀏覽器裏面能充分發揮HTML5的優點,同時又不摒棄主流IE瀏覽器,沿用原來的FLASH運行時,兼容IE6+,iOS 6+, android 4+。兩套運行時,一樣的調用方式,可供用戶任意選用。javascript
上面的一段話是來自 http://fex.baidu.com/webuploader/ 的介紹,如今作的項目須要用到大文件的上傳,以前沒有作過,現有的jquery的uploadify只用於上傳圖片什麼的小文件,查了網上的資料,這個插件好像對於大文件不是很友好,爲了安全起見,使用百度的成熟框架,不管是多文件仍是單個的大文件都是很好用的,沒有不少的問題,關於webuploader的詳細介紹看官網就行:css
個人項目是javaweb,開發環境是MyEclipse,頁面使用jsphtml
一、先將 webuploader-0.1.5.zip 這個文件下載下來:https://github.com/fex-team/webuploader/releases
根據我的的需求放置本身須要的東西就行,所有放到項目裏也能夠,下面是我本身須要的東西:java
二、代碼部分:分爲jsp和servlet部分
一、jsp部分代碼:
- <script type="text/javascript">
- var fileMd5;
- //監聽分塊上傳過程當中的三個時間點
- WebUploader.Uploader.register({
- "before-send-file":"beforeSendFile",
- "before-send":"beforeSend",
- "after-send-file":"afterSendFile",
- },{
- //時間點1:全部分塊進行上傳以前調用此函數
- beforeSendFile:function(file){
- var deferred = WebUploader.Deferred();
- //一、計算文件的惟一標記,用於斷點續傳
- (new WebUploader.Uploader()).md5File(file,0,10*1024*1024)
- .progress(function(percentage){
- $('#item1').find("p.state").text("正在讀取文件信息...");
- })
- .then(function(val){
- fileMd5=val;
- $('#item1').find("p.state").text("成功獲取文件信息...");
- //獲取文件信息後進入下一步
- deferred.resolve();
- });
- return deferred.promise();
- },
- //時間點2:若是有分塊上傳,則每一個分塊上傳以前調用此函數
- beforeSend:function(block){
- var deferred = WebUploader.Deferred();
-
- $.ajax({
- type:"POST",
- url:"<%=basePath%>Video?action=checkChunk",
- data:{
- //文件惟一標記
- fileMd5:fileMd5,
- //當前分塊下標
- chunk:block.chunk,
- //當前分塊大小
- chunkSize:block.end-block.start
- },
- dataType:"json",
- success:function(response){
- if(response.ifExist){
- //分塊存在,跳過
- deferred.reject();
- }else{
- //分塊不存在或不完整,從新發送該分塊內容
- deferred.resolve();
- }
- }
- });
-
- this.owner.options.formData.fileMd5 = fileMd5;
- deferred.resolve();
- return deferred.promise();
- },
- //時間點3:全部分塊上傳成功後調用此函數
- afterSendFile:function(){
- //若是分塊上傳成功,則通知後臺合併分塊
- $.ajax({
- type:"POST",
- url:"<%=basePath%>Video?action=mergeChunks",
- data:{
- fileMd5:fileMd5,
- },
- success:function(response){
- alert("上傳成功");
- var path = "uploads/"+fileMd5+".mp4";
- $("#item1").attr("src",path);
- }
- });
- }
- });
-
- var uploader = WebUploader.create({
- // swf文件路徑
- swf: '<%=basePath%>scripts/webuploader-0.1.5/Uploader.swf',
- // 文件接收服務端。
- server: '<%=basePath%>UploadVideo',
- // 選擇文件的按鈕。可選。
- // 內部根據當前運行是建立,多是input元素,也多是flash.
- pick: {id: '#add_video', <span style="background-color:rgb(255,204,0);">//這個id是你要點擊上傳文件的id,本身設置就好</span>
- multiple:false},
- // 不壓縮image, 默認若是是jpeg,文件上傳前會壓縮一把再上傳!
- resize: true,
- auto:true,
- //開啓分片上傳
- chunked: true,
- chunkSize:10*1024*1024,
-
- accept: {
- //限制上傳文件爲MP4
- extensions: 'mp4',
- mimeTypes: 'video/mp4',
- }
- });
-
- // 當有文件被添加進隊列的時候
- uploader.on( 'fileQueued', function( file ) {
-
- $('#item1').empty();
- $('#item1').html('<div id="' + file.id + '" class="item">'+
- '<a class="upbtn" id="btn" onclick="stop()">[取消上傳]</a>'+
- '<p class="info">' + file.name + '</p>' +
- '<p class="state">等待上傳...</p></div>'
- );
- });
-
- // 文件上傳過程當中建立進度條實時顯示。
- uploader.on( 'uploadProgress', function( file, percentage ) {
- $('#item1').find('p.state').text('上傳中 '+Math.round(percentage * 100) + '%');
- });
-
- uploader.on( 'uploadSuccess', function( file ) {
- $( '#'+file.id ).find('p.state').text('已上傳');
- });
-
- uploader.on( 'uploadError', function( file ) {
- $( '#'+file.id ).find('p.state').text('上傳出錯');
- });
-
- uploader.on( 'uploadComplete', function( file ) {
- $( '#'+file.id ).find('.progress').fadeOut();
- });
-
- function start(){
- uploader.upload();
- $('#btn').attr("onclick","stop()");
- $('#btn').text("取消上傳");
- }
-
- function stop(){
- uploader.stop(true);
- $('#btn').attr("onclick","start()");
- $('#btn').text("繼續上傳");
- }
-
- </script>
二、servlet部分代碼:
servlet部分須要兩個servlet,一個用於接收分塊文件,一個用於合併分塊成一個文件:jquery
一、接收分塊servlet代碼:
- @SuppressWarnings("serial")
- public class UploadVideo extends HttpServlet {
- @Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
- throws ServletException, IOException {
-
- super.doGet(req, resp);
- doPost(req, resp);
- }
- @SuppressWarnings("unchecked")
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
-
- DiskFileItemFactory factory = new DiskFileItemFactory();
- ServletFileUpload sfu = new ServletFileUpload(factory);
- sfu.setHeaderEncoding("utf-8");
-
- String savePath = this.getServletConfig().getServletContext()
- .getRealPath("");
- String folad = "uploads";
- savePath = savePath + "\\"+folad+"\\";
-
- String fileMd5 = null;
- String chunk = null;
-
- try {
- List<FileItem> items = sfu.parseRequest(request);
-
- for(FileItem item:items){
- if(item.isFormField()){
- String fieldName = item.getFieldName();
- if(fieldName.equals("fileMd5")){
- fileMd5 = item.getString("utf-8");
- }
- if(fieldName.equals("chunk")){
- chunk = item.getString("utf-8");
- }
- }else{
- File file = new File(savePath+"/"+fileMd5);
- if(!file.exists()){
- file.mkdir();
- }
- File chunkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
- FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
-
- }
- }
-
- } catch (FileUploadException e) {
-
- e.printStackTrace();
- }
-
- }
- }
二、合併分塊servlet代碼:
- @SuppressWarnings("serial")
- public class Video extends HttpServlet {
-
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- super.doGet(request, response);
- doPost(request, response);
-
- }
-
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- String savePath = this.getServletConfig().getServletContext()
- .getRealPath("");
- String folad = "uploads";
- savePath = savePath + "\\"+folad+"\\";
-
- String action = request.getParameter("action");
-
- if(action.equals("mergeChunks")){
-
-
- String fileMd5 = request.getParameter("fileMd5");
-
-
- File f = new File(savePath+"/"+fileMd5);
- File[] fileArray = f.listFiles(new FileFilter(){
-
- @Override
- public boolean accept(File pathname) {
-
- if(pathname.isDirectory()){
- return false;
- }
- return true;
- }
- });
-
-
- List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
- Collections.sort(fileList,new Comparator<File>() {
- @Override
- public int compare(File o1, File o2) {
-
- if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
- return -1;
- }
- return 1;
- }
- });
-
- File outputFile = new File(savePath+"/"+fileMd5+".mp4");
-
- outputFile.createNewFile();
-
- FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
-
- FileChannel inChannel;
- for(File file : fileList){
- inChannel = new FileInputStream(file).getChannel();
- inChannel.transferTo(0, inChannel.size(), outChnnel);
- inChannel.close();
-
- file.delete();
- }
- outChnnel.close();
-
- File tempFile = new File(savePath+"/"+fileMd5);
- if(tempFile.isDirectory() && tempFile.exists()){
- tempFile.delete();
- }
- System.out.println("合併成功");
- }else if(action.equals("checkChunk")){
-
- String fileMd5 = request.getParameter("fileMd5");
- String chunk = request.getParameter("chunk");
- String chunkSize = request.getParameter("chunkSize");
-
- File checkFile = new File(savePath+"/"+fileMd5+"/"+chunk);
-
- response.setContentType("text/html;charset=utf-8");
-
- if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){
-
- response.getWriter().write("{\"ifExist\":1}");
- }else{
-
- response.getWriter().write("{\"ifExist\":0}");
- }
- }
-
- }
-
- }
至此,大文件上傳的分塊和斷點就ok了,這也只是我本身的項目需求編寫的,這個框架還涵蓋不少的內容和功能,須要你本身去研究了,不過都不是很難,你也能夠去修改它的css和js文件根據本身的需求。android