js下載文件夾的解決方案


需求:

文件批量上傳,支持斷點續傳。

文件批量下載,支持斷點續傳。

使用JS能夠實現批量下載,能夠提供接口從指定url中下載文件並保存在本地指定路徑中。

服務器不需要打包。

支持大文件斷點下載。比如下載10G的文件。

PC端全平台支持。Windows,macOS,Linux

全瀏覽器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safari

 

這篇文章主要介紹了SpringMVC+Ajax實現文件批量上傳和下載功能實例代碼,代碼分為上傳form和上傳ajax,具體實例代碼大家參考下本文

今天做了文件的上傳下載,小小總結一下,基本的web項目建立及SpringMVC框架搭建此處不詳細寫出來了。

上傳form:

<form id="uploadfiles" enctype="multipart/form-data">

    <input type="file" multiple="multiple" id="file_upload" name="file_upload" />

    <input type="button" value="上傳" onclick="upload()" />

</form>

上傳Ajax:

<script type="text/javascript">

/*

 * 上傳文件

 */

function upload(){

  var formData = new FormData($( "#uploadfiles" )[0]);

   $.ajax({

      type: "post",

      url: "./path/upload",

      dataType: "json",

      data: formData,

      /** 

       *必須false才會自動加上正確的Content-Type 

       */

      contentType : false,

      /** 

       * 必須false才會避開jQuery對 formdata 的默認處理 

       * XMLHttpRequest會對 formdata 進行正確的處理 

       */

      processData : false,

      success: function(data){//從后端返回數據進行處理

       if(data){

         alert("上傳成功!");

       }else{

         alert("上傳失敗!");

       }

      },

      error: function(err) {//提交出錯

        $("#msg").html(JSON.stringify(err));//打出響應信息

        alert("服務器無響應");

       }

     });

}

</script>

 

上傳文件塊

<%@ page language="java" import="up6.DBFile" pageEncoding="UTF-8"%>

<%@ page contentType="text/html;charset=UTF-8"%>

<%@ page import="up6.FileBlockWriter" %>

<%@ page import="up6.XDebug" %>

<%@ page import="up6.*" %>

<%@ page import="up6.biz.*" %>

<%@ page import="org.apache.commons.fileupload.FileItem" %>

<%@ page import="org.apache.commons.fileupload.FileItemFactory" %>

<%@ page import="org.apache.commons.fileupload.FileUploadException" %>

<%@ page import="org.apache.commons.fileupload.disk.DiskFileItemFactory" %>

<%@ page import="org.apache.commons.fileupload.servlet.ServletFileUpload" %>

<%@ page import="org.apache.commons.lang.*" %>

<%@ page import="java.net.URLDecoder"%>

<%@ page import="java.util.Iterator"%>

<%@ page import="net.sf.json.JSONObject"%>

<%@ page import="java.util.List"%>

<% out.clear();

String uid          = request.getHeader("uid");//

String id           = request.getHeader("id");

String lenSvr       = request.getHeader("lenSvr");

String lenLoc       = request.getHeader("lenLoc");

String blockOffset  = request.getHeader("blockOffset");

String blockSize    = request.getHeader("blockSize");

String blockIndex   = request.getHeader("blockIndex");

String blockMd5     = request.getHeader("blockMd5");

String complete     = request.getHeader("complete");

String pathSvr      = "";

 

//參數為空

if(  StringUtils.isBlank( uid )

    || StringUtils.isBlank( id )

    || StringUtils.isBlank( blockOffset ))

{

    XDebug.Output("param is null");

    return;

}

 

// Check that we have a file upload request

boolean isMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory = new DiskFileItemFactory();  

ServletFileUpload upload = new ServletFileUpload(factory);

List files = null;

try

{

    files = upload.parseRequest(request);

}

catch (FileUploadException e)

{// 解析文件數據錯誤  

    out.println("read file data error:" + e.toString());

    return;

  

}

 

FileItem rangeFile = null;

// 得到所有上傳的文件

Iterator fileItr = files.iterator();

// 循環處理所有文件

while (fileItr.hasNext())

{

    // 得到當前文件

    rangeFile = (FileItem) fileItr.next();

    if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))

    {

        pathSvr = rangeFile.getString();

        pathSvr = PathTool.url_decode(pathSvr);

    }

}

 

boolean verify = false;

String msg = "";

String md5Svr = "";

long blockSizeSvr = rangeFile.getSize();

if(!StringUtils.isBlank(blockMd5))

{

    md5Svr = Md5Tool.fileToMD5(rangeFile.getInputStream());

}

 

verify = Integer.parseInt(blockSize) == blockSizeSvr;

if(!verify)

{

    msg = "block size error sizeSvr:" + blockSizeSvr + "sizeLoc:" + blockSize;

}

 

if(verify && !StringUtils.isBlank(blockMd5))

{

    verify = md5Svr.equals(blockMd5);

    if(!verify) msg = "block md5 error";

}

 

if(verify)

{

    //保存文件塊數據

    FileBlockWriter res = new FileBlockWriter();

    //僅第一塊創建

    if( Integer.parseInt(blockIndex)==1) res.CreateFile(pathSvr,Long.parseLong(lenLoc));

    res.write( Long.parseLong(blockOffset),pathSvr,rangeFile);

    up6_biz_event.file_post_block(id,Integer.parseInt(blockIndex));

   

    JSONObject o = new JSONObject();

    o.put("msg", "ok");

    o.put("md5", md5Svr);  

    o.put("offset", blockOffset);//基於文件的塊偏移位置

    msg = o.toString();

}

rangeFile.delete();

out.write(msg);

%>

 

下載的jsp頁面代碼根據需求不同自己設計,這里給出jsp代碼:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>

<%@ page contentType="text/html;charset=UTF-8"%>

<%@ page import="up6.*" %>

<%@ page import="up6.model.*" %>

<%@ page import="java.nio.*" %>

<%@ page import="java.nio.channels.*" %>

<%@ page import="java.net.URLDecoder" %>

<%@ page import="java.net.URLEncoder" %>

<%@ page import="org.apache.commons.lang.*" %>

<%@ page import="com.google.gson.FieldNamingPolicy" %>

<%@ page import="com.google.gson.Gson" %>

<%@ page import="com.google.gson.GsonBuilder" %>

<%@ page import="com.google.gson.annotations.SerializedName" %>

<%@ page import="java.io.*" %>

<% out.clear();

String path = request.getContextPath();

String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

 

String fid          = request.getHeader("id");

String blockIndex   = request.getHeader("blockIndex");//基於1

String blockOffset = request.getHeader("blockOffset");//塊偏移,相對於整個文件

String blockSize    = request.getHeader("blockSize");//塊大小(當前需要下載的大小)

String pathSvr      = request.getHeader("pathSvr");//文件在服務器的位置

pathSvr             = PathTool.url_decode(pathSvr);

 

if (  StringUtils.isBlank(fid)

    ||StringUtils.isBlank(blockIndex)

    ||StringUtils.isEmpty(blockOffset)

    ||StringUtils.isBlank(blockSize)

    ||StringUtils.isBlank(pathSvr))

{

    response.setStatus(500);

    response.setHeader("err","參數為空");

    return;

}

File f = new File(pathSvr);

 

//文件不存在

if(!f.exists())

{

    response.setStatus(500);

    OutputStream os = response.getOutputStream();

    System.out.println(String.format("%s 文件不存在",pathSvr));

    os.close();

    return;

}

 

long fileLen = f.length();

 

response.setContentType("application/x-download");

response.setHeader("Pragma","No-cache"); 

response.setHeader("Cache-Control","no-cache");

response.addHeader("Content-Length",blockSize); 

response.setDateHeader("Expires", 0);

 

OutputStream os = response.getOutputStream();

try

{

    RandomAccessFile raf = new RandomAccessFile(pathSvr,"r");

   

    int readToLen = Integer.parseInt(blockSize);

    int readLen = 0;

    raf.seek( Long.parseLong(blockOffset) );//定位索引

    byte[] data = new byte[1048576];

   

    while( readToLen > 0 )

    {

        readLen = raf.read(data,0,Math.min(1048576,readToLen) );

        readToLen -= readLen;

        os.write(data, 0, readLen);

       

    }

    os.flush();

    os.close();

    raf.close();

    os = null;

    response.flushBuffer();

   

    out.clear();

    out = pageContext.pushBody();

}

catch(Exception e)

{

    response.setStatus(500);

    os.close();

    out.close();

    e.printStackTrace();

}

finally

{  

    if(os != null)

    {

        os.close();    

        os = null;

    }

    out.clear();

    out = pageContext.pushBody();

}%>

這里我們進行了優化,下載文件時將不在服務器打包。這個優化對於大型文件的下載來說大幅度提升了效率,而且節省了服務器的資源。當下載用戶比較多的時候,服務器將不會出現打包多個文件導致磁盤空間被占滿的情況。

 

下載頁面如果用Ajax提交請求的話要注意:ajax函數的返回類型只有xml、text、json、html等類型,沒有“流”類型,所以我們要實現ajax下載,不能夠使用相應的ajax函數進行文件下載。但可以用js生成一個form,用這個form提交參數,並返回“流”類型的數據。

例子:

function download(){

    var form=$("<form>");//定義一個form表單

    form.attr("style","display:none");

    form.attr("target","");

    form.attr("method","post");

    form.attr("action","./path/download");//請求url

    var input1=$("<input>");

    input1.attr("type","hidden");

    input1.attr("name","rows");//設置屬性的名字

    input1.attr("value",“test”);//設置屬性的值

    $("body").append(form);//將表單放置在web中

    form.append(input1);

    form.submit();//表單提交      

              }

 

總結

以上所述是小編給大家介紹的SpringMVC+Ajax實現文件批量上傳和下載功能實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。

 

批量上傳效果:

 

批量下載效果

 

網上例子:http://blog.ncmem.com/wordpress/2019/08/28/java批量下載/

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM