js下载文件夹的解决方案
需求:
文件批量上傳,支持斷點續(xù)傳。
文件批量下載,支持斷點續(xù)傳。
使用JS能夠?qū)崿F(xiàn)批量下載,能夠提供接口從指定url中下載文件并保存在本地指定路徑中。
服務器不需要打包。
支持大文件斷點下載。比如下載10G的文件。
PC端全平臺支持。Windows,macOS,Linux
全瀏覽器支持。ie6,ie7,ie8,ie9,ie10,ie11,edge,firefox,chrome,safari
這篇文章主要介紹了SpringMVC+Ajax實現(xiàn)文件批量上傳和下載功能實例代碼,代碼分為上傳form和上傳ajax,具體實例代碼大家參考下本文
今天做了文件的上傳下載,小小總結(jié)一下,基本的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){//從后端返回數(shù)據(jù)進行處理
if(data){
alert("上傳成功!");
}else{
alert("上傳失敗!");
}
},
error: function(err) {//提交出錯
$("#msg").html(JSON.stringify(err));//打出響應信息
alert("服務器無響應");
}
});
}
</script>
上傳文件塊
<%@pagelanguage="java"import="up6.DBFile"pageEncoding="UTF-8"%>
<%@pagecontentType="text/html;charset=UTF-8"%>
<%@pageimport="up6.FileBlockWriter"%>
<%@pageimport="up6.XDebug"%>
<%@pageimport="up6.*"%>
<%@pageimport="up6.biz.*"%>
<%@pageimport="org.apache.commons.fileupload.FileItem"%>
<%@pageimport="org.apache.commons.fileupload.FileItemFactory"%>
<%@pageimport="org.apache.commons.fileupload.FileUploadException"%>
<%@pageimport="org.apache.commons.fileupload.disk.DiskFileItemFactory"%>
<%@pageimport="org.apache.commons.fileupload.servlet.ServletFileUpload"%>
<%@pageimport="org.apache.commons.lang.*"%>
<%@pageimport="java.net.URLDecoder"%>
<%@pageimport="java.util.Iterator"%>
<%@pageimport="net.sf.json.JSONObject"%>
<%@pageimport="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 ="";
//參數(shù)為空
if(StringUtils.isBlank( uid )
|| StringUtils.isBlank( id )
|| StringUtils.isBlank( blockOffset ))
{
XDebug.Output("param is null");
return;
}
// Check that we have a file upload request
booleanisMultipart = ServletFileUpload.isMultipartContent(request);
FileItemFactory factory =newDiskFileItemFactory();
ServletFileUpload upload =newServletFileUpload(factory);
Listfiles =null;
try
{
files = upload.parseRequest(request);
}
catch(FileUploadException e)
{//解析文件數(shù)據(jù)錯誤
out.println("read file data error:"+ e.toString());
return;
}
FileItem rangeFile =null;
//得到所有上傳的文件
IteratorfileItr = files.iterator();
//循環(huán)處理所有文件
while(fileItr.hasNext())
{
//得到當前文件
rangeFile = (FileItem) fileItr.next();
if(StringUtils.equals( rangeFile.getFieldName(),"pathSvr"))
{
pathSvr = rangeFile.getString();
pathSvr = PathTool.url_decode(pathSvr);
}
}
booleanverify =false;
String msg ="";
String md5Svr ="";
longblockSizeSvr = 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)
{
//保存文件塊數(shù)據(jù)
FileBlockWriter res =newFileBlockWriter();
//僅第一塊創(chuàng)建
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 =newJSONObject();
o.put("msg","ok");
o.put("md5", md5Svr);
o.put("offset", blockOffset);//基于文件的塊偏移位置
msg = o.toString();
}
rangeFile.delete();
out.write(msg);
%>
下載的jsp頁面代碼根據(jù)需求不同自己設計,這里給出jsp代碼:
<%@pagelanguage="java"import="java.util.*"pageEncoding="UTF-8"%>
<%@pagecontentType="text/html;charset=UTF-8"%>
<%@pageimport="up6.*"%>
<%@pageimport="up6.model.*"%>
<%@pageimport="java.nio.*"%>
<%@pageimport="java.nio.channels.*"%>
<%@pageimport="java.net.URLDecoder"%>
<%@pageimport="java.net.URLEncoder"%>
<%@pageimport="org.apache.commons.lang.*"%>
<%@pageimport="com.google.gson.FieldNamingPolicy"%>
<%@pageimport="com.google.gson.Gson"%>
<%@pageimport="com.google.gson.GsonBuilder"%>
<%@pageimport="com.google.gson.annotations.SerializedName"%>
<%@pageimport="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","參數(shù)為空");
return;
}
File f =newFile(pathSvr);
//文件不存在
if(!f.exists())
{
response.setStatus(500);
OutputStream os = response.getOutputStream();
System.out.println(String.format("%s文件不存在",pathSvr));
os.close();
return;
}
longfileLen = 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 =newRandomAccessFile(pathSvr,"r");
intreadToLen = Integer.parseInt(blockSize);
intreadLen = 0;
raf.seek( Long.parseLong(blockOffset) );//定位索引
byte[] data =newbyte[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();
}%>
這里我們進行了優(yōu)化,下載文件時將不在服務器打包。這個優(yōu)化對于大型文件的下載來說大幅度提升了效率,而且節(jié)省了服務器的資源。當下載用戶比較多的時候,服務器將不會出現(xiàn)打包多個文件導致磁盤空間被占滿的情況。
下載頁面如果用Ajax提交請求的話要注意:ajax函數(shù)的返回類型只有xml、text、json、html等類型,沒有“流”類型,所以我們要實現(xiàn)ajax下載,不能夠使用相應的ajax函數(shù)進行文件下載。但可以用js生成一個form,用這個form提交參數(shù),并返回“流”類型的數(shù)據(jù)。
例子:
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();//表單提交
}
總結(jié)
以上所述是小編給大家介紹的SpringMVC+Ajax實現(xiàn)文件批量上傳和下載功能實例代碼,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。
批量上傳效果:
批量下載效果
網(wǎng)上例子:http://blog.ncmem.com/wordpress/2019/08/28/java批量下載/
總結(jié)
以上是生活随笔為你收集整理的js下载文件夹的解决方案的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python拆分pubchem SDF文
- 下一篇: 如何通过ip地址来获取主机名字