webUploader大文件断点续传学习心得 多文件

二、Jsp代码:

[javascript] view plain copy

  1. <!-- 断点续传   start-->
  2. <!-- 隐藏域 实时保存上传进度 -->
  3. <input id="jindutiao" type="hidden"/>
  4. <div id="uploader" class="wu-example">
  5. <label class="text-right" style="font-weight:100;float:left;margin-left:15px;width:144px;margin-right:15px;">大文件:</label>
  6. <div class="btns">
  7. <div id="picker" class="webuploader-container">
  8. <div class="webuploader-pick">选择文件</div>
  9. <div id="rt_rt_1bchdejhrarjdvd11h41eoh1nt1" style="position: absolute; top: 0px; left: 0px; width: 88px; height: 35px; overflow: hidden; bottom: auto; right: auto;">
  10. <input id="file_bp" name="file" class="webuploader-element-invisible" type="file" />
  11. <label style="opacity: 0; width: 100%; height: 100%; display: block; cursor: pointer; background: rgb(255, 255, 255) none repeat scroll 0% 0%;"></label>
  12. </div>
  13. </div>
  14. <!-- 文件列表:选择文件后在该div显示 -->
  15. <div id="thelist" class="uploader-list list-group-item clearfix ng-hide" style="margin-left:160px;"></div>
  16. <label class="text-right" style="font-weight:100;float:left;margin-left:15px;width:144px;margin-right:15px;"></label>
  17. <button class="btn m-b-xs btn-sm btn-info btn-addon" id="startOrStopBtn" style="padding:7px 50px;margin-top:20px;">开始上传</button>
  18. </div>
  19. </div>
  20. <!-- 断点续传   end-->

三、js代码

[javascript] view plain copy

  1. <script type="text/javascript">
  2. jQuery(function() {
  3. /*******************初始化参数*********************************/
  4. var $list = $(‘#thelist‘),//文件列表
  5. $btn = $(‘#startOrStopBtn‘),//开始上传按钮
  6. state = ‘pending‘,//初始按钮状态
  7. uploader; //uploader对象
  8. var fileMd5;  //文件唯一标识
  9. /******************下面的参数是自定义的*************************/
  10. var fileName;//文件名称
  11. var oldJindu;//如果该文件之前上传过 已经上传的进度是多少
  12. var count=0;//当前正在上传的文件在数组中的下标,一次上传多个文件时使用
  13. var filesArr=new Array();//文件数组:每当有文件被添加进队列的时候 就push到数组中
  14. var map={};//key存储文件id,value存储该文件上传过的进度
  15. /***************************************************** 监听分块上传过程中的三个时间点 start ***********************************************************/
  16. WebUploader.Uploader.register({
  17. "before-send-file":"beforeSendFile",//整个文件上传前
  18. "before-send":"beforeSend",  //每个分片上传前
  19. "after-send-file":"afterSendFile",  //分片上传完毕
  20. },
  21. {
  22. //时间点1:所有分块进行上传之前调用此函数
  23. beforeSendFile:function(file){
  24. var deferred = WebUploader.Deferred();
  25. //1、计算文件的唯一标记fileMd5,用于断点续传  如果.md5File(file)方法里只写一个file参数则计算MD5值会很慢 所以加了后面的参数:10*1024*1024
  26. (new WebUploader.Uploader()).md5File(file,0,10*1024*1024).progress(function(percentage){
  27. $(‘#‘+file.id ).find(‘p.state‘).text(‘正在读取文件信息...‘);
  28. })
  29. .then(function(val){
  30. $(‘#‘+file.id ).find("p.state").text("成功获取文件信息...");
  31. fileMd5=val;
  32. //获取文件信息后进入下一步
  33. deferred.resolve();
  34. });
  35. fileName=file.name; //为自定义参数文件名赋值
  36. return deferred.promise();
  37. },
  38. //时间点2:如果有分块上传,则每个分块上传之前调用此函数
  39. beforeSend:function(block){
  40. var deferred = WebUploader.Deferred();
  41. $.ajax({
  42. type:"POST",
  43. url:"${ctx}/testController/mergeOrCheckChunks.do?param=checkChunk",  //ajax验证每一个分片
  44. data:{
  45. fileName : fileName,
  46. jindutiao:$("#jindutiao").val(),
  47. fileMd5:fileMd5,  //文件唯一标记
  48. chunk:block.chunk,  //当前分块下标
  49. chunkSize:block.end-block.start//当前分块大小
  50. },
  51. cache: false,
  52. async: false,  // 与js同步
  53. timeout: 1000, //todo 超时的话,只能认为该分片未上传过
  54. dataType:"json",
  55. success:function(response){
  56. if(response.ifExist){
  57. //分块存在,跳过
  58. deferred.reject();
  59. }else{
  60. //分块不存在或不完整,重新发送该分块内容
  61. deferred.resolve();
  62. }
  63. }
  64. });
  65. this.owner.options.formData.fileMd5 = fileMd5;
  66. deferred.resolve();
  67. return deferred.promise();
  68. },
  69. //时间点3:所有分块上传成功后调用此函数
  70. afterSendFile:function(){
  71. //如果分块上传成功,则通知后台合并分块
  72. $.ajax({
  73. type:"POST",
  74. url:"${ctx}/testController/mergeOrCheckChunks.do?param=mergeChunks",  //ajax将所有片段合并成整体
  75. data:{
  76. fileName : fileName,
  77. fileMd5:fileMd5,
  78. },
  79. success:function(data){
  80. count++; //每上传完成一个文件 count+1
  81. if(count<=filesArr.length-1){
  82. uploader.upload(filesArr[count].id);//上传文件列表中的下一个文件
  83. }
  84. //合并成功之后的操作
  85. }
  86. });
  87. }
  88. });
  89. /***************************************************** 监听分块上传过程中的三个时间点 end **************************************************************/
  90. /************************************************************ 初始化WebUploader start ******************************************************************/
  91. uploader = WebUploader.create({
  92. auto:false,//选择文件后是否自动上传
  93. chunked: true,//开启分片上传
  94. chunkSize:10*1024*1024,// 如果要分片,分多大一片?默认大小为5M
  95. chunkRetry: 3,//如果某个分片由于网络问题出错,允许自动重传多少次
  96. threads: 3,//上传并发数。允许同时最大上传进程数[默认值:3]
  97. duplicate : false,//是否重复上传(同时选择多个一样的文件),true可以重复上传
  98. prepareNextFile: true,//上传当前分片时预处理下一分片
  99. swf: ‘${ctx}/resource/webuploader/Uploader.swf‘,// swf文件路径
  100. server: ‘${ctx}/testController/fileSave.do‘,// 文件接收服务端
  101. fileSizeLimit:6*1024*1024*1024,//6G 验证文件总大小是否超出限制, 超出则不允许加入队列
  102. fileSingleSizeLimit:3*1024*1024*1024,  //3G 验证单个文件大小是否超出限制, 超出则不允许加入队列
  103. pick: {
  104. id: ‘#picker‘, //这个id是你要点击上传文件按钮的外层div的id
  105. multiple : false //是否可以批量上传,true可以同时选择多个文件
  106. },
  107. resize: false,  //不压缩image, 默认如果是jpeg,文件上传前会先压缩再上传!
  108. accept: {
  109. //允许上传的文件后缀,不带点,多个用逗号分割
  110. extensions: "txt,jpg,jpeg,bmp,png,zip,rar,war,pdf,cebx,doc,docx,ppt,pptx,xls,xlsx",
  111. mimeTypes: ‘.txt,.jpg,.jpeg,.bmp,.png,.zip,.rar,.war,.pdf,.cebx,.doc,.docx,.ppt,.pptx,.xls,.xlsx‘,
  112. }
  113. });
  114. /************************************************************ 初始化WebUploader end ********************************************************************/
  115. //当有文件被添加进队列的时候(点击上传文件按钮,弹出文件选择框,选择完文件点击确定后触发的事件)
  116. uploader.on(‘fileQueued‘, function(file) {
  117. //限制单个文件的大小 超出了提示
  118. if(file.size>3*1024*1024*1024){
  119. alert("单个文件大小不能超过3G");
  120. return false;
  121. }
  122. /*************如果一次只能选择一个文件,再次选择替换前一个,就增加如下代码*******************************/
  123. //清空文件队列
  124. $list.html("");
  125. //清空文件数组
  126. filesArr=[];
  127. /*************如果一次只能选择一个文件,再次选择替换前一个,就增加以上代码*******************************/
  128. //将选择的文件添加进文件数组
  129. filesArr.push(file);
  130. $.ajax({
  131. type:"POST",
  132. url:"${ctx}/testController/selectProgressByFileName.do",  //先检查该文件是否上传过,如果上传过,上传进度是多少
  133. data:{
  134. fileName : file.name  //文件名
  135. },
  136. cache: false,
  137. async: false,  // 同步
  138. dataType:"json",
  139. success:function(data){
  140. //上传过
  141. if(data>0){
  142. //上传过的进度的百分比
  143. oldJindu=data/100;
  144. //如果上传过 上传了多少
  145. var jindutiaoStyle="width:"+data+"%";
  146. $list.append( ‘<div id="‘ + file.id + ‘" class="item">‘ +
  147. ‘<h4 class="info">‘ + file.name + ‘</h4>‘ +
  148. ‘<p class="state">已上传‘+data+‘%</p>‘ +
  149. ‘<a href="javascript:void(0);" class="btn btn-primary file_btn btnRemoveFile">删除</a>‘ +
  150. ‘<div class="progress progress-striped active">‘ +
  151. ‘<div class="progress-bar" role="progressbar" style="‘+jindutiaoStyle+‘">‘ +
  152. ‘</div>‘ +
  153. ‘</div>‘+
  154. ‘</div>‘ );
  155. //将上传过的进度存入map集合
  156. map[file.id]=oldJindu;
  157. }else{//没有上传过
  158. $list.append( ‘<div id="‘ + file.id + ‘" class="item">‘ +
  159. ‘<h4 class="info">‘ + file.name + ‘</h4>‘ +
  160. ‘<p class="state">等待上传...</p>‘ +
  161. ‘<a href="javascript:void(0);" class="btn btn-primary file_btn btnRemoveFile">删除</a>‘ +
  162. ‘</div>‘ );
  163. }
  164. }
  165. });
  166. uploader.stop(true);
  167. //删除队列中的文件
  168. $(".btnRemoveFile").bind("click", function() {
  169. var fileItem = $(this).parent();
  170. uploader.removeFile($(fileItem).attr("id"), true);
  171. $(fileItem).fadeOut(function() {
  172. $(fileItem).remove();
  173. });
  174. //数组中的文件也要删除
  175. for(var i=0;i<filesArr.length;i++){
  176. if(filesArr[i].id==$(fileItem).attr("id")){
  177. filesArr.splice(i,1);//i是要删除的元素在数组中的下标,1代表从下标位置开始连续删除一个元素
  178. }
  179. }
  180. });
  181. });
  182. //文件上传过程中创建进度条实时显示
  183. uploader.on(‘uploadProgress‘, function(file, percentage) {
  184. var $li = $( ‘#‘+file.id ),
  185. $percent = $li.find(‘.progress .progress-bar‘);
  186. //避免重复创建
  187. if (!$percent.length){
  188. $percent = $(‘<div class="progress progress-striped active">‘ +
  189. ‘<div class="progress-bar" role="progressbar" style="width: 0%">‘ +
  190. ‘</div>‘ +
  191. ‘</div>‘).appendTo( $li ).find(‘.progress-bar‘);
  192. }
  193. //将实时进度存入隐藏域
  194. $("#jindutiao").val(Math.round(percentage * 100));
  195. //根据fielId获得当前要上传的文件的进度
  196. var oldJinduValue = map[file.id];
  197. if(percentage<oldJinduValue && oldJinduValue!=1){
  198. $li.find(‘p.state‘).text(‘上传中‘+Math.round(oldJinduValue * 100) + ‘%‘);
  199. $percent.css(‘width‘, oldJinduValue * 100 + ‘%‘);
  200. }else{
  201. $li.find(‘p.state‘).text(‘上传中‘+Math.round(percentage * 100) + ‘%‘);
  202. $percent.css(‘width‘, percentage * 100 + ‘%‘);
  203. }
  204. });
  205. //上传成功后执行的方法
  206. uploader.on(‘uploadSuccess‘, function( file ) {
  207. //上传成功去掉进度条
  208. $(‘#‘+file.id).find(‘.progress‘).fadeOut();
  209. //隐藏删除按钮
  210. $(".btnRemoveFile").hide();
  211. //隐藏上传按钮
  212. $("#startOrStopBtn").hide();
  213. $(‘#‘+file.id).find(‘p.state‘).text(‘文件已上传成功,系统后台正在处理,请稍后...‘);
  214. });
  215. //上传出错后执行的方法
  216. uploader.on(‘uploadError‘, function( file ) {
  217. errorUpload=true;
  218. $btn.text(‘开始上传‘);
  219. uploader.stop(true);
  220. $(‘#‘+file.id).find(‘p.state‘).text(‘上传出错,请检查网络连接‘);
  221. });
  222. //文件上传成功失败都会走这个方法
  223. uploader.on(‘uploadComplete‘, function( file ) {
  224. });
  225. uploader.on(‘all‘, function(type){
  226. if (type === ‘startUpload‘){
  227. state = ‘uploading‘;
  228. }else if(type === ‘stopUpload‘){
  229. state = ‘paused‘;
  230. }else if(type === ‘uploadFinished‘){
  231. state = ‘done‘;
  232. }
  233. if (state === ‘uploading‘){
  234. $btn.text(‘暂停上传‘);
  235. } else {
  236. $btn.text(‘开始上传‘);
  237. }
  238. });
  239. //上传按钮的onclick时间
  240. $btn.on(‘click‘, function(){
  241. if (state === ‘uploading‘){
  242. uploader.stop(true);
  243. } else {
  244. //当前上传文件的文件名
  245. var currentFileName;
  246. //当前上传文件的文件id
  247. var currentFileId;
  248. //count=0 说明没开始传 默认从文件列表的第一个开始传
  249. if(count==0){
  250. currentFileName=filesArr[0].name;
  251. currentFileId=filesArr[0].id;
  252. }else{
  253. if(count<=filesArr.length-1){
  254. currentFileName=filesArr[count].name;
  255. currentFileId=filesArr[count].id;
  256. }
  257. }
  258. //先查询该文件是否上传过 如果上传过已经上传的进度是多少
  259. $.ajax({
  260. type:"POST",
  261. url:"${ctx}/testController/selectProgressByFileName.do",
  262. data:{
  263. fileName : currentFileName//文件名
  264. },
  265. cache: false,
  266. async: false,  // 同步
  267. dataType:"json",
  268. success:function(data){
  269. //如果上传过 将进度存入map
  270. if(data>0){
  271. map[currentFileId]=data/100;
  272. }
  273. //执行上传
  274. uploader.upload(currentFileId);
  275. }
  276. });
  277. }
  278. });
  279. });
  280. </script>

四、Java代码

[java] view plain copy

    1. //合并、验证分片方法
    2. public void mergeOrCheckChunks(HttpServletRequest request, HttpServletResponse response) {
    3. String param = request.getParameter("param");
    4. String fileName = request.getParameter("fileName");
    5. //当前登录用户信息
    6. SysUser sysUser = (SysUser)request.getSession().getAttribute("user");
    7. String newFilePath = sysUser.getUserId()+"_"+fileName;
    8. String savePath = request.getRealPath("/");
    9. //文件上传的临时文件保存在项目的temp文件夹下 定时删除
    10. savePath = new File(savePath) + "/upload/";
    11. if(param.equals("mergeChunks")){
    12. //合并文件
    13. Jedis jedis =null;
    14. try {
    15. jedis =jedisPool.getResource();
    16. //读取目录里的所有文件
    17. File f = new File(savePath+"/"+jedis.get("fileName_"+fileName));
    18. File[] fileArray = f.listFiles(new FileFilter(){
    19. //排除目录只要文件
    20. @Override
    21. public boolean accept(File pathname) {
    22. if(pathname.isDirectory()){
    23. return false;
    24. }
    25. return true;
    26. }
    27. });
    28. //转成集合,便于排序
    29. List<File> fileList = new ArrayList<File>(Arrays.asList(fileArray));
    30. Collections.sort(fileList,new Comparator<File>() {
    31. @Override
    32. public int compare(File o1, File o2) {
    33. if(Integer.parseInt(o1.getName()) < Integer.parseInt(o2.getName())){
    34. return -1;
    35. }
    36. return 1;
    37. }
    38. });
    39. //截取文件名的后缀名
    40. //最后一个"."的位置
    41. int pointIndex=fileName.lastIndexOf(".");
    42. //后缀名
    43. String suffix=fileName.substring(pointIndex);
    44. //合并后的文件
    45. File outputFile = new File(savePath+"/"+jedis.get("fileName_"+fileName)+suffix);
    46. //创建文件
    47. try {
    48. outputFile.createNewFile();
    49. } catch (IOException e) {
    50. e.printStackTrace();
    51. }
    52. //输出流
    53. FileChannel outChnnel = new FileOutputStream(outputFile).getChannel();
    54. //合并
    55. FileChannel inChannel;
    56. for(File file : fileList){
    57. inChannel = new FileInputStream(file).getChannel();
    58. try {
    59. inChannel.transferTo(0, inChannel.size(), outChnnel);
    60. } catch (IOException e) {
    61. e.printStackTrace();
    62. }
    63. try {
    64. inChannel.close();
    65. } catch (IOException e) {
    66. e.printStackTrace();
    67. }
    68. //删除分片
    69. file.delete();
    70. }
    71. try {
    72. outChnnel.close();
    73. } catch (IOException e) {
    74. e.printStackTrace();
    75. }
    76. //清除文件夹
    77. File tempFile = new File(savePath+"/"+jedis.get("fileName_"+fileName));
    78. if(tempFile.isDirectory() && tempFile.exists()){
    79. tempFile.delete();
    80. }
    81. Map<String, String> resultMap=new HashMap<>();
    82. //将文件的最后上传时间和生成的文件名返回
    83. resultMap.put("lastUploadTime", jedis.get("lastUploadTime_"+newFilePath));
    84. resultMap.put("pathFileName", jedis.get("fileName_"+fileName)+suffix);
    85. /****************清除redis中的相关信息**********************/
    86. //合并成功后删除redis中的进度信息
    87. jedis.del("jindutiao_"+newFilePath);
    88. //合并成功后删除redis中的最后上传时间,只存没上传完成的
    89. jedis.del("lastUploadTime_"+newFilePath);
    90. //合并成功后删除文件名称与该文件上传时生成的存储分片的临时文件夹的名称在redis中的信息  key:上传文件的真实名称   value:存储分片的临时文件夹名称(由上传文件的MD5值+时间戳组成)
    91. //如果下次再上传同名文件  redis中将存储新的临时文件夹名称  没有上传完成的还要保留在redis中 直到定时任务生效
    92. jedis.del("fileName_"+fileName);
    93. Gson gson=new Gson();
    94. String json=gson.toJson(resultMap);
    95. PrintWriterJsonUtils.printWriter(response, json);
    96. } catch (Exception e) {
    97. e.printStackTrace();
    98. }finally{
    99. jedisPool.returnResource(jedis);
    100. }
    101. }else if(param.equals("checkChunk")){
    102. /*************************检查当前分块是否上传成功**********************************/
    103. String fileMd5 = request.getParameter("fileMd5");
    104. String chunk = request.getParameter("chunk");
    105. String chunkSize = request.getParameter("chunkSize");
    106. String jindutiao=request.getParameter("jindutiao");//文件上传的实时进度
    107. Jedis jedis =null;
    108. try {
    109. jedis =jedisPool.getResource();
    110. //将当前进度存入redis
    111. jedis.set("jindutiao_"+newFilePath, jindutiao);
    112. //将系统当前时间转换为字符串
    113. Date date=new Date();
    114. SimpleDateFormat formatter=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    115. String lastUploadTime=formatter.format(date);
    116. //将最后上传时间以字符串形式存入redis
    117. jedis.set("lastUploadTime_"+newFilePath, lastUploadTime);
    118. //自定义文件名: 时间戳(13位)
    119. String tempFileName= String.valueOf(System.currentTimeMillis());
    120. if(jedis.get("fileName_"+fileName)==null || "".equals(jedis.get("fileName_"+fileName))){
    121. //将文件名与该文件上传时生成的存储分片的临时文件夹的名称存入redis
    122. //文件上传时生成的存储分片的临时文件夹的名称由MD5和时间戳组成
    123. jedis.set("fileName_"+fileName, fileMd5+tempFileName);
    124. }
    125. File checkFile = new File(savePath+"/"+jedis.get("fileName_"+fileName)+"/"+chunk);
    126. response.setContentType("text/html;charset=utf-8");
    127. //检查文件是否存在,且大小是否一致
    128. if(checkFile.exists() && checkFile.length()==Integer.parseInt(chunkSize)){
    129. //上传过
    130. try {
    131. response.getWriter().write("{\"ifExist\":1}");
    132. } catch (IOException e) {
    133. e.printStackTrace();
    134. }
    135. }else{
    136. //没有上传过
    137. try {
    138. response.getWriter().write("{\"ifExist\":0}");
    139. } catch (IOException e) {
    140. e.printStackTrace();
    141. }
    142. }
    143. } catch (Exception e) {
    144. e.printStackTrace();
    145. }finally{
    146. jedisPool.returnResource(jedis);
    147. }
    148. }
    149. }
    150. //保存上传分片
    151. public void fileSave(HttpServletRequest request, HttpServletResponse response) {
    152. DiskFileItemFactory factory = new DiskFileItemFactory();
    153. ServletFileUpload sfu = new ServletFileUpload(factory);
    154. sfu.setHeaderEncoding("utf-8");
    155. String savePath = request.getRealPath("/");
    156. savePath = new File(savePath) + "/upload/";
    157. String fileMd5 = null;
    158. String chunk = null;
    159. String fileName=null;
    160. try {
    161. List<FileItem> items = sfu.parseRequest(request);
    162. for(FileItem item:items){
    163. //上传文件的真实名称
    164. fileName=item.getName();
    165. if(item.isFormField()){
    166. String fieldName = item.getFieldName();
    167. if(fieldName.equals("fileMd5")){
    168. try {
    169. fileMd5 = item.getString("utf-8");
    170. } catch (UnsupportedEncodingException e) {
    171. e.printStackTrace();
    172. }
    173. }
    174. if(fieldName.equals("chunk")){
    175. try {
    176. chunk = item.getString("utf-8");
    177. } catch (UnsupportedEncodingException e) {
    178. e.printStackTrace();
    179. }
    180. }
    181. }else{
    182. Jedis jedis =null;
    183. try {
    184. jedis =jedisPool.getResource();
    185. File file = new File(savePath+"/"+jedis.get("fileName_"+fileName));
    186. if(!file.exists()){
    187. file.mkdir();
    188. }
    189. File chunkFile = new File(savePath+"/"+jedis.get("fileName_"+fileName)+"/"+chunk);
    190. FileUtils.copyInputStreamToFile(item.getInputStream(), chunkFile);
    191. } catch (Exception e) {
    192. e.printStackTrace();
    193. }finally{
    194. jedisPool.returnResource(jedis);
    195. }
    196. }
    197. }
    198. } catch (FileUploadException e) {
    199. e.printStackTrace();
    200. }
    201. }
    202. //当有文件添加进队列时 通过文件名查看该文件是否上传过 上传进度是多少
    203. public String selectProgressByFileName(String fileName) {
    204. String jindutiao="";
    205. Jedis jedis =null;
    206. try {
    207. jedis =jedisPool.getResource();
    208. if(null!=fileName && !"".equals(fileName)){
    209. jindutiao=jedis.get("jindutiao_"+fileName);
    210. }
    211. }catch(Exception e){
    212. e.printStackTrace();
    213. }finally{
    214. jedisPool.returnResource(jedis);
    215. }
    216. return jindutiao;
    217. }

原文地址:https://www.cnblogs.com/yesu/p/8267118.html

时间: 2024-08-10 11:59:58

webUploader大文件断点续传学习心得 多文件的相关文章

大数据linux学习心得体会

刚开始接触大数据的时候,还是很迷茫的,要学习掌握的东西很多,linux,mysql,java,scala,看到这些的确很头大,于是乎也没有什么思绪,只能一个接着一个的去学习,先去学习linux,看到之后是一脸懵逼,之前没接触过底层的东西,所以开始庄装VM,在linux环境下去指定各种命令,让自己去熟悉这些命令,打好基础才能去掌握现在新的技术,不要去盲目学习,好高骛远,你又不是天才,所以脚踏实地才是你的选择. 原文地址:https://www.cnblogs.com/cclvls/p/121061

php大文件断点续传

该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开始. 如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子.但是因为时间的关系还有工作的关系,我只能罢休了.最后我选择了百度的WebUploader来实现前端所需. 如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的.刚开始的时

HTML5 大文件断点续传完整思路整理

需求: 支持大文件批量上传(20G)和下载,同时需要保证上传期间用户电脑不出现卡死等体验: 内网百兆网络上传速度为12MB/S 服务器内存占用低 支持文件夹上传,文件夹中的文件数量达到1万个以上,且包含层级结构. 支持PC端全平台操作系统,Windows,Linux,Mac 支持文件和文件夹的批量下载,断点续传.刷新页面后继续传输.关闭浏览器后保留进度信息. 支持文件夹批量上传下载,服务器端保留文件夹层级结构,服务器端文件夹层级结构与本地相同. 支持断点续传,关闭浏览器或刷新浏览器后仍然能够保留

Flash大文件断点续传解决方案

核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开始. 如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子.但是因为时间的关系还有工作的关系,我只能罢休了.最后我选择了百度的WebUploader来实现前端所需. 如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的

php解决大文件断点续传

核心原理: 该项目核心就是文件分块上传.前后端要高度配合,需要双方约定好一些数据,才能完成大文件分块,我们在项目中要重点解决的以下问题. * 如何分片: * 如何合成一个文件: * 中断了从哪个分片开始. 如何分,利用强大的js库,来减轻我们的工作,市场上已经能有关于大文件分块的轮子,虽然程序员的天性曾迫使我重新造轮子.但是因为时间的关系还有工作的关系,我只能罢休了.最后我选择了百度的WebUploader来实现前端所需. 如何合,在合之前,我们还得先解决一个问题,我们如何区分分块所属那个文件的

iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载+使用输出流代替文件句柄

前言:本篇讲解,在前篇iOS开发之网络编程--使用NSURLConnection实现大文件断点续传下载的基础上,使用输出流代替文件句柄实现大文件断点续传.    在实际开发中,输入输出流用的比较少,但是用起来也是很方便的.iOS开发用到的输入输出流和在Java中的输入输出流是几乎一样的,本质也是一个意思:将网络返回的数据当做流来处理.    输入输出的理解:输入到哪里?输出到哪里?这个问题不难理解,输入输出是要站着服务器角度来思考的,下面用图来解释:    代码关键词: 1.在接收到响应头的代理

web之大文件断点续传

之前仿造uploadify写了一个HTML5版的文件上传插件,没看过的朋友可以点此先看一下~得到了不少朋友的好评,我自己也用在了项目中,不论是用户头像上传,还是各种媒体文件的上传,以及各种个性的业务需求,都能得到满足.小小开心了一把. 但无论插件再怎么灵活,也难以应付所有的需求,比如,你要上传一个2G的文件.以现在我们的网速,恐怕再快也得传半小时.要命的是,如果你在上传到90%的时候不小心关掉了浏览器,或者是手一抖摁了F5,完了,一切还得从头再来.这种用户体验简直太糟糕了.所以,断点续传就十分有

jsp解决大文件断点续传

我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用. 这次项目的需求: 支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,ie8,ie9,Chrome,Firefox,360安全浏览器,并且刷新浏览器后仍然能够续传,重启浏览器(关闭浏览器后再打开)仍然能够继续上传,重启电脑后仍然能够上传 支持文件夹的上传,要求服务端能够保留层级结构,并且能够续传.需要支持10万个以上的文件夹上传. 支持低版本的系统和浏览器,因为这个项目

文件上传控件-如何上传文件-大文件断点续传

需求: 项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在20G内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以20G来进行限制. PC端全平台支持,要求支持Windows,Mac,Linux 支持所有浏览器. 支持文件批量上传 支持文件夹上传,且要求在服务端保留层级结构.文件夹数量要求支持到10W. 支持大文件断点续传,要求刷新浏览器,重启浏览器,重启电脑后仍然能够继续上传.文件大小要求能够支持到20个G. 支持自动加载本地文件,要求能够自动加载指定的本地文件.