前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >快速学习-断点续传解决方案

快速学习-断点续传解决方案

作者头像
cwl_java
发布2020-01-14 14:59:46
1.2K0
发布2020-01-14 14:59:46
举报
文章被收录于专栏:cwl_Java

6.3上传文件

6.3.1 断点续传解决方案

通常视频文件都比较大,所以对于媒资系统上传文件的需求要满足大文件的上传要求。http协议本身对上传文件大 小没有限制,但是客户的网络环境质量、电脑硬件环境等参差不齐,如果一个大文件快上传完了网断了,电断了没 有上传完成,需要客户重新上传,这是致命的,所以对于大文件上传的要求最基本的是断点续传。

什么是断点续传:

引用百度百科:断点续传指的是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个 部分,每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传 下载未完成的部分,而没有必要从头开始上传下载,断点续传可以提高节省操作时间,提高用户体验性。

如下图:

上传流程如下: 1、上传前先把文件分成块 2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传 3、各分块上传完成最后合并文件

文件下载则同理。

6.3.2 文件分块与合并

为了更好的理解文件分块上传的原理,下边用java代码测试文件的分块与合并。

6.3.2.1 文件分块

文件分块的流程如下: 1、获取源文件长度 2、根据设定的分块文件的大小计算出块数 3、从源文件读数据依次向每一个块文件写数据。

代码语言:javascript
复制
//测试文件分块
    @Test
    public void testChunk() throws IOException {
        //源文件
        File sourceFile = new File("E:\\ffmpeg_test\\lucene.avi");
        //块文件目录
        String chunkFileFolder = "E:\\ffmpeg_test\\chunks\\";

        //先定义块文件大小
        long chunkFileSize = 1 * 1024 * 1024;

        //块数
        long chunkFileNum = (long) Math.ceil(sourceFile.length() * 1.0 /chunkFileSize);

        //创建读文件的对象
        RandomAccessFile raf_read = new RandomAccessFile(sourceFile,"r");

        //缓冲区
        byte[] b = new byte[1024];
        for(int i=0;i<chunkFileNum;i++){
            //块文件
            File chunkFile = new File(chunkFileFolder+i);
            //创建向块文件的写对象
            RandomAccessFile raf_write = new RandomAccessFile(chunkFile,"rw");
            int len = -1;

            while((len = raf_read.read(b))!=-1){

                raf_write.write(b,0,len);
                //如果块文件的大小达到 1M开始写下一块儿
                if(chunkFile.length()>=chunkFileSize){
                    break;
                }
            }
            raf_write.close();


        }
        raf_read.close();
    }
6.3.2.2 文件合并

文件合并流程: 1、找到要合并的文件并按文件合并的先后进行排序。 2、创建合并文件 3、依次从合并的文件中读取数据向合并文件写入数

代码语言:javascript
复制
//测试文件合并
    @Test
    public void testMergeFile() throws IOException {
        //块文件目录
        String chunkFileFolderPath = "E:\\ffmpeg_test\\chunks\\";
        //块文件目录对象
        File chunkFileFolder = new File(chunkFileFolderPath);
        //块文件列表
        File[] files = chunkFileFolder.listFiles();
        //将块文件排序,按名称升序
        List<File> fileList = Arrays.asList(files);
        Collections.sort(fileList, new Comparator<File>() {
            @Override
            public int compare(File o1, File o2) {
                if(Integer.parseInt(o1.getName())>Integer.parseInt(o2.getName())){
                    return 1;
                }
                return -1;

            }
        });

        //合并文件
        File mergeFile = new File("E:\\ffmpeg_test\\lucene_merge.avi");
        //创建新文件
        boolean newFile = mergeFile.createNewFile();

        //创建写对象
        RandomAccessFile raf_write = new RandomAccessFile(mergeFile,"rw");

        byte[] b = new byte[1024];
        for(File chunkFile:fileList){
            //创建一个读块文件的对象
            RandomAccessFile raf_read = new RandomAccessFile(chunkFile,"r");
            int len = -1;
            while((len = raf_read.read(b))!=-1){
                raf_write.write(b,0,len);
            }
            raf_read.close();
        }
        raf_write.close();
    }

6.3.3 前端页面

6.3.3.1 WebUploader介绍

如何在web页面实现断点续传?

常见的方案有: 1、通过Flash上传,比如SWFupload、Uploadify。 2、安装浏览器插件,变相的pc客户端,用的比较少。 3、Html5

随着html5的流行,本项目采用Html5完成文件分块上传。 本项目使用WebUploader完成大文件上传功能的开发,WebUploader官网地址:

http://fexteam.gz01.bdysite.com/webuploader/

特性如下:

使用WebUploader上传流程如下:

6.3.3.1 钩子方法

在webuploader中提供很多钩子方法,下边列出一些重要的:

本项目使用如下钩子方法: 1)before-send-file 在开始对文件分块儿之前调用,可以做一些上传文件前的准备工作,比如检查文件目录是否创建完成等。

2)before-send 在上传文件分块之前调用此方法,可以请求服务端检查分块是否存在,如果已存在则此分块儿不再上传。

3)after-send-file 在所有分块上传完成后触发,可以请求服务端合并分块文件。

注册钩子方法源代码:

代码语言:javascript
复制
WebUploader.Uploader.register({
			"before‐send‐file": "beforeSendFile",
			"before‐send": "beforeSend",
			"after‐send‐file": "afterSendFile"
		}
6.3.3.2 构建WebUploader

使用webUploader前需要创建webUploader对象。 指定上传分块的地址:/api/media/upload/uploadchunk

代码语言:javascript
复制
this.uploader = WebUploader.create({
			swf: "/static/plugins/webuploader/dist/Uploader.swf", //上传文件的flash文件,浏览器不支持h5时启动 
			flashserver:"/api/media/upload/uploadchunk",//上传分块的服务端地址,注意跨域问题 
			fileVal:"file",//文件上传域的name 
			pick:"#picker",//指定选择文件的按钮容器 
			auto:false,//手动触发上传 
			disableGlobalDnd:true,//禁掉整个页面的拖拽功能 
			chunked:true,// 是否分块上传 
			chunkSize:1*1024*1024, // 分块大小(默认5M) 
			threads:3, // 开启多个线程(默认3个) 
			prepareNextFile:true// 允许在文件传输时提前把下一个文件准备好 
			} 
		)
6.3.3.3 before-send-file

文件开始上传前前端请求服务端准备上传工作。 参考源代码如下:

代码语言:javascript
复制
type: "POST", 
url: "/api/media/upload/register", 
data: { 
	// 文件唯一表示 
	fileMd5:this.fileMd5, 
	fileName: file.name, 
	fileSize:file.size, 
	mimetype:file.type, 
	fileExt:file.ext 
}
6.3.3.4 before-send

上传分块前前端请求服务端校验分块是否存在。 参考源代码如下:

代码语言:javascript
复制
type:"POST", 
url:"/api/media/upload/checkchunk", 
data:{ 
	// 文件唯一表示 
	fileMd5:this.fileMd5, 
	// 当前分块下标 
	chunk:block.chunk, 
	// 当前分块大小 
	chunkSize:block.end‐block.start 
}
6.3.3.5 after-send-file

在所有分块上传完成后触发,可以请求服务端合并分块文件 参考代码如下:

代码语言:javascript
复制
type:"POST", 
url:"/api/media/upload/mergechunks", 
data:{ 
	fileMd5:this.fileMd5, 
	fileName: file.name, 
	fileSize:file.size, 
	mimetype:file.type, 
	fileExt:file.ext 
}

6.3.5 媒资服务端编写

6.3.5.1 业务流程

服务端需要实现如下功能: 1、上传前检查上传环境 检查文件是否上传,已上传则直接返回。 检查文件上传路径是否存在,不存在则创建。 2、分块检查 检查分块文件是否上传,已上传则返回true。 未上传则检查上传路径是否存在,不存在则创建。 3、分块上传 将分块文件上传到指定的路径。 4、合并分块 将所有分块文件合并为一个文件。 在数据库记录文件信息。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 6.3上传文件
    • 6.3.1 断点续传解决方案
      • 6.3.2 文件分块与合并
        • 6.3.2.1 文件分块
        • 6.3.2.2 文件合并
      • 6.3.3 前端页面
        • 6.3.3.1 WebUploader介绍
        • 6.3.3.1 钩子方法
        • 6.3.3.2 构建WebUploader
        • 6.3.3.3 before-send-file
        • 6.3.3.4 before-send
        • 6.3.3.5 after-send-file
      • 6.3.5 媒资服务端编写
        • 6.3.5.1 业务流程
    相关产品与服务
    对象存储
    对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档