㈠ java中文件大小超過多大需要斷點續傳
這個不太難吧?
假設A給B傳文件F(1024位元組)。第一次B接收了512位元組,那麼第二次連接A就應該從513位元組開始傳輸。
也就是說,在第二次傳輸時,B要提供「我要從513位元組開始傳送文件F」的信息,然後A使用FileInputStream構建輸入流讀取本地文件,使用skip(512)方法跳過文件F的前512位元組再傳送文件,之後B將數據追加(append)到先前接收的文件末尾即可。
進一步考慮,如果要實現多線程傳送,即分塊傳輸,也同樣的道理。假如B要求分作兩塊同時傳輸,那麼A啟動兩個線程,一個從513位元組讀到768位元組(工256位元組),第二個線程從769位元組到1024位元組即可。
如果你要從網路上下載文件,就是說A方不是你實現的,那麼你要先確認A方支不支持斷電續傳功能(HTTP1.1),然後你查閱下HTTP1.1協議,在HTTP1.1版本里,可以通過設置請求包頭某個欄位的信息(使用URLConnection創建連接並使用setRequestProperty(String key, String value) 方法設置)從而精確讀取文件的某一段數據的。注意,基於HTTP斷點續傳的關鍵是1.1版本,1.0版本是不支持的。
㈡ java web斷點續傳,我用的是fileupload來做的上傳。
使用Struts2上傳文件:
Struts文件上傳需要使用File Upload Filter。Filter Upload Filter使用一些默認的規則:
Form中的<s:file name="image"></s:file>標簽對應著Action類中的三個屬性分別是:上傳文件(java.io.File類型),文件名(java.lang.String類型),文件類型(java.lang.String類型,例如:image/jpeg)。命名規約為:
文件:名字與<s:file>標簽中的name屬性一致,這里為:image
文件名:文件 + FileName,這里為:imageFileName
文件類型:文件 + ContentType,這里為:imageContentType
所以針對上述<s:file name="image"></s:file>表示啊的上傳文件的JSP和Action類被別為:
imageUpload.jsp:
[html]view plain
<%@pagecontentType="text/html;charset=UTF-8"language="java"%>
<%@taglibprefix="s"uri="/struts-tags"%>
<html>
<head><title>ImageUpload</title></head>
<body>
<h1>ImageUploadPage</h1>
<s:formaction="imageUpload"method="post"enctype="multipart/form-data">
<s:filename="image"></s:file>
<s:submit></s:submit>
</s:form>
</body>
</html>
packagecom.jpleasure;
importcom.opensymphony.xwork2.ActionSupport;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
{
privateFileimage;
privateStringimageFileName;
privateStringimageContentType;
publicFilegetImage(){
returnimage;
}
publicvoidsetImage(Fileimage){
this.image=image;
}
publicStringgetImageFileName(){
returnimageFileName;
}
publicvoidsetImageFileName(StringimageFileName){
this.imageFileName=imageFileName;
}
(){
returnimageContentType;
}
publicvoidsetImageContentType(StringimageContentType){
this.imageContentType=imageContentType;
}
publicStringexecute(){
if(image!=null){
System.out.println("filenameis:"+this.imageFileName);
System.out.println("filecontenttypeis:"+this.imageContentType);
System.out.println("filelengthis:"+this.image.length());
}
returnSUCCESS;
}
}
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<result>/success.jsp</result>
</action>
packagecom.jpleasure;
importcom.opensymphony.xwork2.ActionSupport;
importjava.io.File;
importjava.io.InputStream;
importjava.io.FileInputStream;
importjava.io.FileNotFoundException;
{
privateFileimage;
privateStringimageFileName;
privateStringimageContentType;
=null;
(){
returnimageInputStream;
}
publicvoidsetImageInputStream(InputStreamimageInputStream){
this.imageInputStream=imageInputStream;
}
publicFilegetImage(){
returnimage;
}
publicvoidsetImage(Fileimage){
this.image=image;
}
publicStringgetImageFileName(){
returnimageFileName;
}
publicvoidsetImageFileName(StringimageFileName){
this.imageFileName=imageFileName;
}
(){
returnimageContentType;
}
publicvoidsetImageContentType(StringimageContentType){
this.imageContentType=imageContentType;
}
publicStringexecute(){
if(image!=null){
System.out.println("filenameis:"+this.imageFileName);
System.out.println("filecontenttypeis:"+this.imageContentType);
System.out.println("filelengthis:"+this.image.length());
try{
this.imageInputStream=newFileInputStream(image);
}catch(FileNotFoundExceptione){
e.printStackTrace();
}
}
returnSUCCESS;
}
}
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<resultname="success"type="stream">
<paramname="contentType">image/pjpeg</param>
<paramname="inputName">imageInputStream</param>
<paramname="contentDisposition">attachment;filename="image.jpg"</param>
<paramname="bufferSize">1024</param>
</result>
</action>
<struts>
<packagename="myPackage"extends="struts-default">
<interceptor-refname="fileUpload">
<paramname="maximumSize">2MB</param>
<paramname="allowedTypes">text/html,image/jpeg</param>
</interceptor-ref>
<interceptor-refname="basicStack"/>
<actionname="imageUpload"class="com.jpleasure.ImageUploadAction">
<resultname="success"type="stream">
<paramname="contentType">image/pjpeg</param>
<paramname="inputName">imageInputStream</param>
<paramname="contentDisposition">
attachment;filename="image.jpg"
</param>
<paramname="bufferSize">1024</param>
</result>
</action>
</package>
</struts>
ImageUploadAction.java:
[html]view plain
Struts.xml配置文件:
[html]view plain
這樣當我們選中上傳文件,提交的時候:文件內容會以File類型的方式放在image聲明的變數中。文件的名字將會被放在imageFileName命名的變數中,文件的類型被放在imageContentType命名的變數中。
文件下載:
文件下載需要使用一個特殊的Result,stream類型的Result。Stream類型的Result主要用來處理文件下載操作。
處理原理為:所有的下載文件都是將一個二進制的流寫入到HttpResponse中去。在Action類中定義一個InputSream類型的二進制流,在Result返回給用戶的時候返回給用戶。
擴展上述的代碼,將上傳來的文件直接下載給用戶:
ImageUploadAction中需要追加一個InputSream類型的對象,並且指向上傳的文件,代碼如下,紅色部分表示變化:
[html]view plain
配置文件為,紅色為變化部分:
[html]view plain
ContentType表示下載文件的類型。
InputName表示Action類中用來下載文件的欄位的名字。
ContentDisposition用來控制文件下載的一些信息,包括是否打開另存對話框,下載文件名等。
BufferSize表示文件下載時使用的緩沖區的大小。
實際項目開發的考慮:
控制上傳文件的類型和最大允許上傳文件的size
使用File Upload Intercepter的參數可盈控制上傳文件的類型和最大允許上傳文件的size。例如:
[html]view plain
上述表示允許上傳jpeg和html類型的文件,且最大文件上傳size為2MB
顯示錯誤信息:
可以使用如下key表示的message來顯示文件上傳出錯的提示信息:
消息Key 說明
struts.messages.error.uploading 文件無法正常上傳時的公共錯誤
struts.messages.error.file.too.large 文件大小超過最大允許size時的錯誤提示
struts.messages.error.content.type.not.allowed 文件類型不在上傳文件允許類型中的錯誤提示
㈢ 用java向hdfs上傳文件時,如何實現斷點續傳
@Component("javaLargeFileUploaderServlet")
@WebServlet(name = "javaLargeFileUploaderServlet", urlPatterns = { "/javaLargeFileUploaderServlet" })
public class UploadServlet extends HttpRequestHandlerServlet
implements HttpRequestHandler {
private static final Logger log = LoggerFactory.getLogger(UploadServlet.class);
@Autowired
UploadProcessor uploadProcessor;
@Autowired
FileUploaderHelper fileUploaderHelper;
@Autowired
ExceptionCodeMappingHelper exceptionCodeMappingHelper;
@Autowired
Authorizer authorizer;
@Autowired
StaticStateIdentifierManager staticStateIdentifierManager;
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws IOException {
log.trace("Handling request");
Serializable jsonObject = null;
try {
// extract the action from the request
UploadServletAction actionByParameterName =
UploadServletAction.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.action));
// check authorization
checkAuthorization(request, actionByParameterName);
// then process the asked action
jsonObject = processAction(actionByParameterName, request);
// if something has to be written to the response
if (jsonObject != null) {
fileUploaderHelper.writeToResponse(jsonObject, response);
}
}
// If exception, write it
catch (Exception e) {
exceptionCodeMappingHelper.processException(e, response);
}
}
private void checkAuthorization(HttpServletRequest request, UploadServletAction actionByParameterName)
throws MissingParameterException, AuthorizationException {
// check authorization
// if its not get progress (because we do not really care about authorization for get
// progress and it uses an array of file ids)
if (!actionByParameterName.equals(UploadServletAction.getProgress)) {
// extract uuid
final String fileIdFieldValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId, false);
// if this is init, the identifier is the one in parameter
UUID clientOrJobId;
String parameter = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);
if (actionByParameterName.equals(UploadServletAction.getConfig) && parameter != null) {
clientOrJobId = UUID.fromString(parameter);
}
// if not, get it from manager
else {
clientOrJobId = staticStateIdentifierManager.getIdentifier();
}
// call authorizer
authorizer.getAuthorization(
request,
actionByParameterName,
clientOrJobId,
fileIdFieldValue != null ? getFileIdsFromString(fileIdFieldValue).toArray(new UUID[] {}) : null);
}
}
private Serializable processAction(UploadServletAction actionByParameterName, HttpServletRequest request)
throws Exception {
log.debug("Processing action " + actionByParameterName.name());
Serializable returnObject = null;
switch (actionByParameterName) {
case getConfig:
String parameterValue = fileUploaderHelper.getParameterValue(request, UploadServletParameter.clientId, false);
returnObject =
uploadProcessor.getConfig(
parameterValue != null ? UUID.fromString(parameterValue) : null);
break;
case verifyCrcOfUncheckedPart:
returnObject = verifyCrcOfUncheckedPart(request);
break;
case prepareUpload:
returnObject = prepareUpload(request);
break;
case clearFile:
uploadProcessor.clearFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));
break;
case clearAll:
uploadProcessor.clearAll();
break;
case pauseFile:
List<UUID> uuids = getFileIdsFromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));
uploadProcessor.pauseFile(uuids);
break;
case resumeFile:
returnObject =
uploadProcessor.resumeFile(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)));
break;
case setRate:
uploadProcessor.setUploadRate(UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId)),
Long.valueOf(fileUploaderHelper.getParameterValue(request, UploadServletParameter.rate)));
break;
case getProgress:
returnObject = getProgress(request);
break;
}
return returnObject;
}
List<UUID> getFileIdsFromString(String fileIds) {
String[] splittedFileIds = fileIds.split(",");
List<UUID> uuids = Lists.newArrayList();
for (int i = 0; i < splittedFileIds.length; i++) {
uuids.add(UUID.fromString(splittedFileIds[i]));
}
return uuids;
}
private Serializable getProgress(HttpServletRequest request)
throws MissingParameterException {
Serializable returnObject;
String[] ids =
new Gson()
.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId), String[].class);
Collection<UUID> uuids = Collections2.transform(Arrays.asList(ids), new Function<String, UUID>() {
@Override
public UUID apply(String input) {
return UUID.fromString(input);
}
});
returnObject = Maps.newHashMap();
for (UUID fileId : uuids) {
try {
ProgressJson progress = uploadProcessor.getProgress(fileId);
((HashMap<String, ProgressJson>) returnObject).put(fileId.toString(), progress);
}
catch (FileNotFoundException e) {
log.debug("No progress will be retrieved for " + fileId + " because " + e.getMessage());
}
}
return returnObject;
}
private Serializable prepareUpload(HttpServletRequest request)
throws MissingParameterException, IOException {
// extract file information
PrepareUploadJson[] fromJson =
new Gson()
.fromJson(fileUploaderHelper.getParameterValue(request, UploadServletParameter.newFiles), PrepareUploadJson[].class);
// prepare them
final HashMap<String, UUID> prepareUpload = uploadProcessor.prepareUpload(fromJson);
// return them
return Maps.newHashMap(Maps.transformValues(prepareUpload, new Function<UUID, String>() {
public String apply(UUID input) {
return input.toString();
};
}));
}
private Boolean verifyCrcOfUncheckedPart(HttpServletRequest request)
throws IOException, MissingParameterException, FileCorruptedException, FileStillProcessingException {
UUID fileId = UUID.fromString(fileUploaderHelper.getParameterValue(request, UploadServletParameter.fileId));
try {
uploadProcessor.verifyCrcOfUncheckedPart(fileId,
fileUploaderHelper.getParameterValue(request, UploadServletParameter.crc));
}
catch (InvalidCrcException e) {
// no need to log this exception, a fallback behaviour is defined in the
// throwing method.
// but we need to return something!
return Boolean.FALSE;
}
return Boolean.TRUE;
}
}
㈣ JAVA WEB怎麼實現大文件上傳
解決這種大文件上傳不太可能用web上傳的方式,只有自己開發插件或是當門客戶端上傳,或者用現有的ftp等。
1)開發一個web插件。用於上傳文件。
2)開發一個FTP工具,不用web上傳。
3)用現有的FTP工具。
下面是幾款不錯的插件,你可以試試:
1)Jquery的uploadify插件。具體使用。你可以看幫助文檔。
2)網上有一個Web大文件斷點續傳控制項:http://www.cnblogs.com/xproer/archive/2012/02/17/2355440.html
此控制項支持100G文件的斷點續傳操作,提供了完善的開發文檔,支持文件MD5驗證,支持文件批量上傳。
JavaUploader免費開源的,是用applet實現的,需要簽名才能在瀏覽器上用,支持斷點。缺點是收費。
3)applet也是一種方式,MUPLOAD組件就是以APPLET方式處理的。
如果你不需要訪問用戶的硬碟文件,那你可以使用FTP上傳,也支持斷點。但只要你訪問用戶磁碟,又要支持斷點,那必須要簽名的。不然瀏覽器不知道你的身份。
㈤ 求Java 以上超大文件上傳和斷點續傳伺服器的實現
提供個思路
使用2個介面
介面一,獲取伺服器已上傳文件的大小
介面二,依據介面一的大小從本地文件指定位置讀取文件上傳
㈥ java 用什麼方式實現超大文件的斷點處理
1.2之後, django支持在項目中使用多個DB. 那麼到底如何使用呢? 1. 修改 settings.py 01DATABASES = { 02 'default': { 03 'NAME': 'app_data', 04 'ENGINE': 'django.db.backends.postgresql_psycopg2', 05 'USER': 'postgres_user', 06 'PASS...
㈦ java 斷點續傳
這個不太難吧?
假設A給B傳文件F(1024位元組)。第一次B接收了512位元組,那麼第二次連接A就應該從513位元組開始傳輸。
也就是說,在第二次傳輸時,B要提供「我要從513位元組開始傳送文件F」的信息,然後A使用FileInputStream構建輸入流讀取本地文件,使用skip(512)方法跳過文件F的前512位元組再傳送文件,之後B將數據追加(append)到先前接收的文件末尾即可。
進一步考慮,如果要實現多線程傳送,即分塊傳輸,也同樣的道理。假如B要求分作兩塊同時傳輸,那麼A啟動兩個線程,一個從513位元組讀到768位元組(工256位元組),第二個線程從769位元組到1024位元組即可。
如果你要從網路上下載文件,就是說A方不是你實現的,那麼你要先確認A方支不支持斷電續傳功能(HTTP1.1),然後你查閱下HTTP1.1協議,在HTTP1.1版本里,可以通過設置請求包頭某個欄位的信息(使用URLConnection創建連接並使用setRequestProperty(String key, String value) 方法設置)從而精確讀取文件的某一段數據的。注意,基於HTTP斷點續傳的關鍵是1.1版本,1.0版本是不支持的。
補充:
嗯,查到了,是設置range屬性,即setRequestProperty("range", "bytes=513-1024").你可以使用迅雷下載某個文件,然後從」線程信息「中就可以看到這個http1.1斷點續傳的所有行為信息了。
希望能解決您的問題。
㈧ 利用Java實現斷點上傳
1、Java中用於進行流操作都是java.lang.io包下,如果藉助於網路則用Socket。
2、獲取上傳速度可以根據時間量和上傳的量得出。至於斷點得記錄上次已上傳的量。
㈨ 求java web使用webuploader斷點上傳代碼,或者java web的斷點上傳代碼
github上面有個一項目是關於大文件分片上傳的
https://github.com/xu0ying0jie/XuFileServer
項目中有編譯打包好的可以直接使用,github上有詳細描述使用方法
㈩ 求web 以上超大文件上傳和斷點續傳伺服器的實現
web 以上超大文件上傳和斷點續傳伺服器的實現
javaweb上傳文件
上傳文件的jsp中的部分
上傳文件同樣可以使用form表單向後端發請求,也可以使用 ajax向後端發請求
1.通過form表單向後端發送請求
<form id="postForm" action="${pageContext.request.contextPath}/UploadServlet" method="post" enctype="multipart/form-data">
<div class="bbxx wrap">
<inputtype="text" id="side-profile-name" name="username" class="form-control">
<inputtype="file" id="example-file-input" name="avatar">
<button type="submit" class="btn btn-effect-ripple btn-primary">Save</button>
</div>
</form>
改進後的代碼不需要form標簽,直接由控制項來實現。開發人員只需要關注業務邏輯即可。JS中已經幫我們封閉好了
this.post_file = function ()
{
$.each(this.ui.btn, function (i, n) { n.hide();});
this.ui.btn.stop.show();
this.State = this.Config.state.Posting;//
this.app.postFile({ id: this.fileSvr.id, pathLoc: this.fileSvr.pathLoc, pathSvr:this.fileSvr.pathSvr,lenSvr: this.fileSvr.lenSvr, fields: this.fields });
};
通過監控工具可以看到控制項提交的數據,非常的清晰,調試也非常的簡單。
2.通過ajax向後端發送請求
$.ajax({
url : "${pageContext.request.contextPath}/UploadServlet",
type : "POST",
data : $( '#postForm').serialize(),
success : function(data) {
$( '#serverResponse').html(data);
},
error : function(data) {
$( '#serverResponse').html(data.status + " : " + data.statusText + " : " + data.responseText);
}
});
ajax分為兩部分,一部分是初始化,文件在上傳前通過AJAX請求通知服務端進行初始化操作
this.md5_complete = function (json)
{
this.fileSvr.md5 = json.md5;
this.ui.msg.text("MD5計算完畢,開始連接伺服器...");
this.event.md5Complete(this, json.md5);//biz event
var loc_path = encodeURIComponent(this.fileSvr.pathLoc);
var loc_len = this.fileSvr.lenLoc;
var loc_size = this.fileSvr.sizeLoc;
var param = jQuery.extend({}, this.fields, this.Config.bizData, { md5: json.md5, id: this.fileSvr.id, lenLoc: loc_len, sizeLoc: loc_size, pathLoc: loc_path, time: new Date().getTime() });
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名
, url: this.Config["UrlCreate"]
, data: param
, success: function (sv)
{
_this.svr_create(sv);
}
, error: function (req, txt, err)
{
_this.Manager.RemoveQueuePost(_this.fileSvr.id);
alert("向伺服器發送MD5信息錯誤!" + req.responseText);
_this.ui.msg.text("向伺服器發送MD5信息錯誤");
_this.ui.btn.cancel.show();
_this.ui.btn.stop.hide();
}
, complete: function (req, sta) { req = null; }
});
};
在文件上傳完後向伺服器發送通知
this.post_complete = function (json)
{
this.fileSvr.perSvr = "100%";
this.fileSvr.complete = true;
$.each(this.ui.btn, function (i, n)
{
n.hide();
});
this.ui.process.css("width", "100%");
this.ui.percent.text("(100%)");
this.ui.msg.text("上傳完成");
this.Manager.arrFilesComplete.push(this);
this.State = this.Config.state.Complete;
//從上傳列表中刪除
this.Manager.RemoveQueuePost(this.fileSvr.id);
//從未上傳列表中刪除
this.Manager.RemoveQueueWait(this.fileSvr.id);
var param = { md5: this.fileSvr.md5, uid: this.uid, id: this.fileSvr.id, time: new Date().getTime() };
$.ajax({
type: "GET"
, dataType: 'jsonp'
, jsonp: "callback" //自定義的jsonp回調函數名稱,默認為jQuery自動生成的隨機函數名
, url: _this.Config["UrlComplete"]
, data: param
, success: function (msg)
{
_this.event.fileComplete(_this);//觸發事件
_this.post_next();
}
, error: function (req, txt, err) { alert("文件-向伺服器發送Complete信息錯誤!" + req.responseText); }
, complete: function (req, sta) { req = null; }
});
};
這里需要處理一個MD5秒傳的邏輯,當伺服器存在相同文件時,不需要用戶再上傳,而是直接通知用戶秒傳
this.post_complete_quick = function ()
{
this.fileSvr.perSvr = "100%";
this.fileSvr.complete = true;
this.ui.btn.stop.hide();
this.ui.process.css("width", "100%");
this.ui.percent.text("(100%)");
this.ui.msg.text("伺服器存在相同文件,快速上傳成功。");
this.Manager.arrFilesComplete.push(this);
this.State = this.Config.state.Complete;
//從上傳列表中刪除
this.Manager.RemoveQueuePost(this.fileSvr.id);
//從未上傳列表中刪除
this.Manager.RemoveQueueWait(this.fileSvr.id);
//添加到文件列表
this.post_next();
this.event.fileComplete(this);//觸發事件
};
這里可以看到秒傳的邏輯是非常 簡單的,並不是特別的復雜。
var form = new FormData();
form.append("username","zxj");
form.append("avatar",file);
//var form = new FormData($("#postForm")[0]);
$.ajax({
url:"${pageContext.request.contextPath}/UploadServlet",
type:"post",
data:form,
processData:false,
contentType:false,
success:function(data){
console.log(data);
}
});
java部分
文件初始化的邏輯,主要代碼如下
FileInf fileSvr= new FileInf();
fileSvr.id = id;
fileSvr.fdChild = false;
fileSvr.uid = Integer.parseInt(uid);
fileSvr.nameLoc = PathTool.getName(pathLoc);
fileSvr.pathLoc = pathLoc;
fileSvr.lenLoc = Long.parseLong(lenLoc);
fileSvr.sizeLoc = sizeLoc;
fileSvr.deleted = false;
fileSvr.md5 = md5;
fileSvr.nameSvr = fileSvr.nameLoc;
//所有單個文件均以uuid/file方式存儲
PathBuilderUuid pb = new PathBuilderUuid();
fileSvr.pathSvr = pb.genFile(fileSvr.uid,fileSvr);
fileSvr.pathSvr = fileSvr.pathSvr.replace("\\","/");
DBConfig cfg = new DBConfig();
DBFile db = cfg.db();
FileInf fileExist = new FileInf();
boolean exist = db.exist_file(md5,fileExist);
//資料庫已存在相同文件,且有上傳進度,則直接使用此信息
if(exist && fileExist.lenSvr > 1)
{
fileSvr.nameSvr = fileExist.nameSvr;
fileSvr.pathSvr = fileExist.pathSvr;
fileSvr.perSvr = fileExist.perSvr;
fileSvr.lenSvr = fileExist.lenSvr;
fileSvr.complete = fileExist.complete;
db.Add(fileSvr);
//觸發事件
up6_biz_event.file_create_same(fileSvr);
}//此文件不存在
else
{
db.Add(fileSvr);
//觸發事件
up6_biz_event.file_create(fileSvr);
FileBlockWriter fr = new FileBlockWriter();
fr.CreateFile(fileSvr.pathSvr,fileSvr.lenLoc);
}
接收文件塊數據,在這個邏輯中我們接收文件塊數據。控制項對數據進行了優化,可以方便調試。如果用監控工具可以看到控制項提交的數據。
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);
註:
1. 上面的java部分的代碼可以直接使用,只需要將上傳的圖片路徑及收集數據並將數據寫入到資料庫即可
2. 上面上傳文件使用到了位元組流,其實還可以使用別的流,這個需要讀者自己在下面完善測試
3. BeanUtils是一個工具 便於將實體對應的屬性賦給實體
4. 上傳文件不能使用 request.getParameter("")獲取參數了,而是直接將request解析,通過判斷每一項是文件還是非文件,然後進行相應的操作(文件的話就是用流來讀取,非文件的話,暫時保存到一個map中。)