我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。

首先我们需要了解的是上传文件三要素:

1.表单提交方式:post (get方式提交有大小限制,post没有)

2.表单的enctype属性:必须设置为multipart/form-data.

3.表单必须有文件上传项:file,且文件项需要给定name值

上传文件夹需要增加一个属性webkitdirectory,像这样:

不过webkitdirectory属性有个问题,只能支持高版本的chrome,不能支持低版本的IE,如ie6,ie7,ie8,不能做到全浏览器适配,运行环境比较单一。

js中可以判断文件夹中文件数量及文件夹大小是否符合要求,不符合要求不能向后台提交:

前台HTML模板

this.GetHtmlFiles =function()

{

varacx ="";

acx +='

\

\

\

\

HttpUploader程序开发.pdf

\

(35%)

\

1000.23MB

\

\

15.3MB 20KB/S 10:02:00

\

\

\

取消

\

继续

\

停止

\

删除

\

';

acx +='

';

//文件夹模板

acx +='

\

\

\

\

HttpUploader程序开发.pdf

\

(35%)

\

1000.23MB

\

\

15.3MB 20KB/S 10:02:00

\

\

\

取消

\

继续

\

停止

\

删除

\

';

acx +='

';

//上传列表

acx +='

\

\

选择多个文件\

选择文件夹\

粘贴文件和目录\

安装控件\

\

\

\

\

清除已完成文件\

\

';

returnacx;

};

选择文件,选择文件夹,粘贴文件和文件夹的逻辑

this.open_files =function(json)

{

for(vari = 0, l = json.files.length; i < l; ++i)

{

this.addFileLoc(json.files[i]);

}

setTimeout(function() { _this.PostFirst(); },500);

};

this.open_folders =function(json)

{

for(vari = 0, l = json.folders.length; i < l; ++i) {

this.addFolderLoc(json.folders[i]);

}

setTimeout(function() { _this.PostFirst(); }, 500);

};

this.paste_files =function(json)

{

for(vari = 0, l = json.files.length; i < l; ++i)

{

this.addFileLoc(json.files[i]);

}

};

后台在接收文件夹时不同之处在需要用MultipartHttpServletRequest

booleanisMultipart = ServletFileUpload.isMultipartContent(request);

FileItemFactory factory =newDiskFileItemFactory();

ServletFileUpload upload =newServletFileUpload(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);

}

}

server端的包和类

文件块处页面,验证代码部分

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)

{

//保存文件块数据

FileBlockWriter res =newFileBlockWriter();

//仅第一块创建

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);

生成文件名称的逻辑

publicStringgenFile(intuid,Stringmd5,StringnameLoc)throwsIOException

{

SimpleDateFormatfmtDD =newSimpleDateFormat("dd");

SimpleDateFormatfmtMM =newSimpleDateFormat("MM");

SimpleDateFormatfmtYY =newSimpleDateFormat("yyyy");

Datedate =newDate();

StringstrDD = fmtDD.format(date);

StringstrMM = fmtMM.format(date);

StringstrYY = fmtYY.format(date);

Stringpath =this.getRoot() +"/";

path = path.concat(strYY);

path = path.concat("/");

path = path.concat(strMM);

path = path.concat("/");

path = path.concat(strDD);

path = path.concat("/");

path = path.concat(md5);

path = path.concat(".");

path = path.concat(PathTool.getExtention(nameLoc));

Filefl =newFile(path);

returnfl.getCanonicalPath();//

}

以下是service层做的处理:

整体模块划分如下:

其中数据类实体逻辑处理如下

publicclassFileInf{

publicFileInf(){}

publicStringid="";

publicStringpid="";

publicStringpidRoot="";

/***表示当前项是否是一个文件夹项。*/

publicbooleanfdTask=false;

/是否是文件夹中的子文件///

publicbooleanfdChild=false;

/***用户ID。与第三方系统整合使用。*/

publicintuid=0;

/***文件在本地电脑中的名称*/

publicStringnameLoc="";

/***文件在服务器中的名称。*/

publicStringnameSvr="";

/***文件在本地电脑中的完整路径。示例:D:\Soft\QQ2012.exe */

publicStringpathLoc="";

/***文件在服务器中的完整路径。示例:F:\\ftp\\uer\\md5.exe*/

publicStringpathSvr="";

/***文件在服务器中的相对路径。示例:/www/web/upload/md5.exe*/

publicStringpathRel="";

/***文件MD5*/

publicStringmd5="";

/***数字化的文件长度。以字节为单位,示例:120125*/

publiclonglenLoc=0;

/***格式化的文件尺寸。示例:10.03MB*/

publicStringsizeLoc="";

/***文件续传位置。*/

publiclongoffset=0;

/***已上传大小。以字节为单位 */

publiclonglenSvr=0;

/***已上传百分比。示例:10%*/

publicStringperSvr="0%";

publicbooleancomplete=false;

publicDatePostedTime=newDate();

publicbooleandeleted=false;

/***是否已经扫描完毕,提供给大型文件夹使用,大型文件夹上传完毕后开始扫描。*/

publicbooleanscaned=false;

}

后台数据库中的逻辑基本上都用到了上面的实体类

文件数据表操作类如下

加载所有未完成的文件列表

publicStringGetAllUnComplete(intf_uid)

{

StringBuildersb =newStringBuilder();

sb.append("select ");

sb.append(" f_id");

sb.append(",f_fdTask");

sb.append(",f_nameLoc");

sb.append(",f_pathLoc");

sb.append(",f_md5");

sb.append(",f_lenLoc");

sb.append(",f_sizeLoc");

sb.append(",f_pos");

sb.append(",f_lenSvr");

sb.append(",f_perSvr");

sb.append(",f_complete");

sb.append(",f_pathSvr");//fix(2015-03-16):修复无法续传文件的问题。

sb.append(" from up6_files ");//change(2015-03-18):联合查询文件夹数据

sb.append(" where f_uid=? and f_deleted=0 and f_fdChild=0 and f_complete=0 and f_scan=0");//fix(2015-03-18):只加载未完成列表

ArrayList files =newArrayList();

DbHelperdb =newDbHelper();

PreparedStatement cmd = db.GetCommand(sb.toString());

try{

cmd.setInt(1, f_uid);

ResultSet r = db.ExecuteDataSet(cmd);

while(r.next())

{

FileInff =newFileInf();

f.uid= f_uid;

f.id= r.getString(1);

f.fdTask= r.getBoolean(2);

f.nameLoc= r.getString(3);

f.pathLoc= r.getString(4);

f.md5= r.getString(5);

f.lenLoc= r.getLong(6);

f.sizeLoc= r.getString(7);

f.offset= r.getLong(8);

f.lenSvr= r.getLong(9);

f.perSvr= r.getString(10);

f.complete= r.getBoolean(11);

f.pathSvr= r.getString(12);//fix(2015-03-19):修复无法续传文件的问题。

files.add(f);

}

r.close();

cmd.getConnection().close();

cmd.close();

}catch(SQLExceptione) {

//TODOAuto-generated catch block

e.printStackTrace();

}

if(files.size() < 1)returnnull;

Gsong =newGson();

returng.toJson( files);//bug:arrFiles为空时,此行代码有异常

}

实现后的整体效果如下

文件夹上传完后的效果

服务器保存的文件夹数据,而且层级结构与本地客户端是一致的。这在OA系统中,或者网盘系统中使用时是非常有用的

uploader java_java-webuploader+Java如何实现分片+断点续传相关推荐

  1. php - 基于 webuploader 视频大文件分片分段上传,支持断点续传(刷新、关闭页面、重新上传、网络中断等情况)带进度条,前端后端都有示例源码详细教程

    效果图 文件上传前先检测该文件是否已上传,如果已上传提示 "文件已存在",如果未上传则直接上传. 基于 php+webuploader的大文件分片上传,带进度条,支持断点续传(刷新 ...

  2. Java 中 List 分片的 5 种方法!

    作者 | 王磊 来源 | Java中文社群(ID:javacn666) 转载请联系授权(微信ID:GG_Stone) 前些天在实现 MyBatis 批量插入时遇到了一个问题,当批量插入的数据量比较大时 ...

  3. java对文件分片处理

    java对文件分片处理 前言 文件分割与合并是一个常见需求,比如:上传大文件时,可以先分割成小块,传到服务器后,再进行合并. 1.文件切割 //预分配文件占用磁盘空间"r"表示只读 ...

  4. 利用webuploader实现超大文件分片上传、断点续传

    之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需 ...

  5. WebUploader 实现大文件的断点续传功能

    断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个片段进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部 ...

  6. .NetCore+WebUploader实现大文件分片上传

    项目要求通过网站上传大文件,比如视频文件,通过摸索实现了文件分片来上传,然后后台进行合并. 使用了开源的前台上传插件WebUploader(http://fex.baidu.com/webupload ...

  7. webuploader 实现大文件 分片上传

    webuploader 分片上传文件 最近研究了下大文件上传的方法,找到了webuploader js 插件进行大文件上传. 使用 使用webuploader分成简单直选要引入 <!--引入CS ...

  8. java实现超大文件断点续传

    转载是大佬:https://blog.csdn.net/riemann_/article/details/89484471 真是阳光普照大地啊!!!!作为不要脸的我也转载来给大家看看 我测试时用5G的 ...

  9. java视频文件分片上传

    Java视频分块上传 环境:springboot2.5.6+jdk1.8 1.在启动类中配置静态资源映射 springboot项目中配置了静态资源映射之后就启动项目之后就可以通过地址访问了 @Spri ...

  10. Java之Redis分片机制

    1. Redis分片机制 1.1 分片机制说明 前提说明: redis可以通过修改内存的大小 实现数据的保存.但是内存的资源不易设置的过大,因为很多的时间都浪费在内存的寻址中. 需求: 如果有海量的数 ...

最新文章

  1. mcs-51单片机视频教程——从硬件到c语言手把手的教,手把手从零教你学51单片机...
  2. linux烧录文件的格式,制作emmc 烧录文件
  3. 8086简单的指令流水线_在8086微处理器中执行流水线的指令和概念的步骤
  4. elasticsearch aggregations_elasticsearch 笔记三 之聚合查询之分组计数、平均数、最大值、script、最小值、总和...
  5. C++中vector的用法
  6. Excel VBA函数和过程调用方法总结(跨文件调用函数和过程)
  7. 计算机学数字电子基础知识,什么是数字电路?数字电路基础知识
  8. 多年前的csdn账号找回啦
  9. NLPIR在线系统介绍
  10. ssis oracle配置,[SSIS][Oracle]安裝 Oracle Driver 提供 SSIS 使用
  11. VS2017出现的神奇错误HRSULT:0x80041FE2
  12. vue生命周期的快速记忆方法
  13. shell脚本:从1加到100的几种实现方式
  14. linux原子锁原理,了解Linux的锁与同步、原子加(atomic_add)
  15. 计算机主机usb端口使用不了,电脑USB接口不能用怎么办解决教程
  16. Win10播放视频卡顿怎么解决
  17. Linux下怎么进入波浪线目录,linux 波浪线 ~ 使用方法
  18. Excel应用-使用VBA自动绘制所有适用类型的Excel图表(代码及效果图)
  19. 解决Mscomctl.ocx丢失的问题
  20. 【Unity】关于U3d与bip骨骼适配

热门文章

  1. java常见基础面试题
  2. Avro, Protocol Buffers 、Thrift的联系与区别
  3. 数据结构 详解(C++)
  4. excel2019关闭后有残留进程_农药残留检测仪电路设计方案(原理图+PCB+BOM)
  5. 上海大学计算机获奖上央视新闻,央视获奖新闻照片竟是电脑合成
  6. Java宣言的时候,JAVA面向对象-对象宣言
  7. python自动化学习_Python自动化学习笔记(二)
  8. c语言四个零,输入任意四个整数(0到10),运算符只有加减乘除,还有括号.每个数只能且必须用一次。要求判断这些表达的结果中是否有24。如果有,输出计算表达式:如输入4,6,1...
  9. html5 crop,HTML5内联SVG autocrop空格
  10. js实现表格任意框选_[R] 在表格中插入图形 - formattable + htmlwidgets