二、Jsp代码:

[javascript] view plaincopy
  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 plaincopy
  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 plaincopy
  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

webUploader大文件断点续传学习心得 多文件相关推荐

  1. php文件断点续传,php文件下载限速,文件断点续传,多线程下载文件原理解析

    文件下载限速 首先,我们写一段使用php输出文件给浏览器下载的代码<?php /** * Created by PhpStorm. * User: tioncico * Date: 19-2-4 ...

  2. python3 读取.plist文件_Python学习笔记 -5 - 文件操作

    Python文件操作 读写文件是最常见的IO操作,在磁盘上读写文件的功能都是由操作系统提供的,操作系统不允许普通的程序直接操作磁盘(大部分程序都需要间接的通过操作系统来完成对硬件的操作),所以,读写文 ...

  3. python文件操作学习心得

    infile= open("E:\\python项目\\test1_5\\tan.txt","r+") print("Name of file: &q ...

  4. python shutil删除文件_Python学习笔记组织文件之shutil模块

    随笔记录方便自己和同路人查阅. #------------------------------------------------我是可耻的分割线--------------------------- ...

  5. java jdom 读取xml文件_jdom学习:读取xml文件

    本文转自http://www.blogjava.net/fjq639/archive/2005/12/20/24806.html 用JDOM读取XML文件需先用org.jdom.input.SAXBu ...

  6. oracle财务软件心得,Oracle密码文件学习心得

    下面总结了一些Oracle密码文件的学习心得,希望对大家有所帮助. (一)创建Oracle密码文件的命令 orapwd file= password= entries=最大数目 这里的file命名规则 ...

  7. 飞秋教程:文件断点续传

    飞秋新版本增加了文件断点续传功能,省去了传大文件时因为网络问题中断又得重新开始传的烦恼,节省时间,提高速度,对于已传过的大文件,重新接收时能实现秒传. 默认情况下文件断点续传功能是在文件大于1M时才开 ...

  8. 【飞秋教程】文件断点续传

    文件断点续传 飞秋新版本增加了文件断点续传功能,省去了传大文件时因为网络问题中断又得重新开始传的烦恼,节省时间,提高速度,对于已传过的大文件,重新接收时能实现秒传. 默认情况下文件断点续传功能是在文件 ...

  9. 【最佳实践】OSS开源工具ossutil-大文件断点续传

    经常碰到内部同学或者外部客户问ossutil关于大文件断点续传的问题.本文简单描述下原理并举例说明. 用户可从这里获取ossutil. 官网:https://help.aliyun.com/docum ...

  10. 大数据全方位学习路线

    大数据全方位学习路线 一.大数据处理流程 上图是一个简化的大数据处理流程图,大数据处理的主要流程包括数据收集.数据存储.数据处理.数据应用等主要环节.下面我们逐一对各个环节所需要的技术栈进行讲解: 1 ...

最新文章

  1. 物体三维识别论文介绍——基于霍夫投票
  2. HDFS副本设置——默认3
  3. 干货:RabbitMQ消息队列基本原理介绍
  4. SCARA机器人与 DELTA机器人
  5. Python学习14 模块和包
  6. 前端通信:ajax设计方案(五)--- 集成promise规范,更优雅的书写代码(改迭代已作废,移步迭代10)...
  7. MySQL上线,检查数据库设计的“十条合规”
  8. Android嵌入式安卓触摸屏|4418开发板平台
  9. MYSQL IFNULL函数的使用
  10. 再说一次,别去外包!
  11. android图片资源加密,手机游戏加密之2d资源加密
  12. 用Python写的WiFi暴力破解工具(字典),已封装!!
  13. Java计算机毕业设计德云社票务系统源码+系统+数据库+lw文档
  14. 精简版WIN XP安装日文输入法
  15. int类型转换byte类型
  16. 责任链模式的高级用法
  17. 世界银行提供10亿美元贷款助印度发展太阳能
  18. 【数据仓库】1.数据模型
  19. excel单元格斜线_含金量100%的9个Excel函数公式,全部100%掌握的都是超级高手!...
  20. 数据密集型系统设计:索引及存储(B树、LSM树、OLTP及OLAP)

热门文章

  1. C++入门项目——通讯管理系统
  2. 迅捷CAD编辑器中图纸加密的办法
  3. 常用射频接头之2.92mm
  4. 【编译原理】词法分析(C/C++源代码+实验报告)
  5. ElasticSearch
  6. 节约里程法解决VRP物流配送路径优化问题及局部优化改进-matlab代码
  7. Linux程序设计(虚拟机 Ubuntu 编译程序)
  8. I/O模型+Nginx基本配置
  9. DOS窗口的一些简单介绍
  10. WordPress直接调用头像地址