项目难点——断点续传分片上传(代码片段)

NPE~ NPE~     2023-03-07     723

关键词:

项目难点——【2】断点续传、分片上传

1 文件分片

在网络请求中,如果我们有时是上传大文件,可能由于网络原因,导致上传断断续续,很难一次性上传成功,那么这个时候我们就需要将大文件分块,分成一小块一小块的,然后结合端点续传技术,实现大文件上传。

2 断点续传

2.1 概念

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

断点续传效果图:

流程如下:

1、前端上传前先把文件分成块
2、一块一块的上传,上传中断后重新上传,已上传的分块则不用再上传
3、各分块上传完成最后在服务端合并文件

2.2 分片与合并测试

①文件分片

具体流程:
1. 获取源文件长度
2. 根据设定的分块文件大小计算块数
3. 从源文件读数据依次向每一个块文件写入数据
/**
 * @author zhouYi
 * @description 大文件测试处理
 * @date 2023/2/17 8:34
 */
public class BigFileTest 

    //测试文件分片
    @Test
    public void testChunk() throws IOException 
        File sourceFile = new File("D:\\\\系统默认\\\\桌面\\\\gra-res\\\\mv\\\\test.mp4");
        //分片文件路径
        String chunkPath = "d:/chunk/";
        File chunkFolder = new File(chunkPath);
        if(!chunkFolder.exists())
            chunkFolder.mkdirs();
        
        //分片文件大小
        long chunkSize = 1024 * 1024 * 1;
        //分片数量[向上取整,1.5M则需要两块分片传输]
        long chunkNum = (long) Math.ceil(sourceFile.length() * 1.0 / chunkSize);
        System.out.println("分块总数:" + chunkNum);
        //缓冲区大小
        byte[] b = new byte[1024];
        //使用RandomAccessFile访问文件["r",读]
        RandomAccessFile raf_read = new RandomAccessFile(sourceFile, "r");
        //将文件分片
        for (int i = 0; i < chunkNum; i++) 
            //创建分片文件
            File file = new File(chunkPath + i);
            if(file.exists())
                file.delete();
            
            boolean newFile = file.createNewFile();
            if(newFile)
                //如果创建成功则向分片文件中写入数据
                RandomAccessFile raf_write = new RandomAccessFile(file, "rw");
                int len = -1;
                while((len = raf_read.read(b)) != -1)
                    //从缓冲区读取数据
                    raf_write.write(b, 0, len);
                    if(file.length() >= chunkSize)
                        break;
                    
                
                raf_write.close();
                System.out.println("完成分片" + i);
            
        
        raf_read.close();
    

结果:

②文件合并

  • 合并流程:
1、找到要合并的文件并按文件合并的先后进行排序。
2、创建合并文件
3、依次从合并的文件中读取数据向合并文件写入数
  • 具体代码:
@Test
    public void testMerge() throws IOException 
        //片文件目录
        File chunkFolder = new File("d:/chunk/");
        //原始文件
        File originalFile = new File("D:\\\\系统默认\\\\桌面\\\\gra-res\\\\mv\\\\test.mp4");
        //合并后的文件
        File mergeFile = new File("D:\\\\系统默认\\\\桌面\\\\gra-res\\\\mv\\\\test2.mp4");
        if(mergeFile.exists())
            mergeFile.delete();
        
        //创建新的合并文件
        mergeFile.createNewFile();
        //用于写文件
        RandomAccessFile raf_write = new RandomAccessFile(mergeFile, "rw");
        //指针指向文件顶端
        raf_write.seek(0);
        //缓冲区
        byte[] b = new byte[1024];
        //分块列表
        File[] fileArray = chunkFolder.listFiles();
        //转成集合便于排序【保证数据正确,以便可以恢复数据】
        List<File> fileList = Arrays.asList(fileArray);
        //从小到大排序
        Collections.sort(fileList, Comparator.comparingInt(o -> Integer.parseInt(o.getName())));
        //合并文件
        for (File chunkFile : fileList) 
            RandomAccessFile raf_read = new RandomAccessFile(chunkFile, "rw");
            int len = -1;
            while((len = raf_read.read(b)) != -1)
                raf_write.write(b, 0, len);
            
            raf_read.close();
        
        raf_write.close();
        //校验文件是否成功恢复【如果文件相同,则二者MD5值相同】
        try(
            FileInputStream fileInputStream = new FileInputStream(originalFile);
            FileInputStream mergeFileStream = new FileInputStream(mergeFile);
        )
            //原始文件MD5
            String originalMd5 = DigestUtils.md5Hex(fileInputStream);
            //合并文件的md5
            String mergeFileMd5 = DigestUtils.md5Hex(mergeFileStream);
            if(originalMd5.equals(mergeFileMd5))
                System.out.println("合并文件成功");
            else
                System.out.println("合并文件失败");
            
        

    


成功播放:

3 实现思路

3.1 前端对文件分块

3.2 前端校验并上传

3.3 前端发送合并请求

3.4 服务端传到分布式文件系统

3.5 总结

  1. 前端对文件分块
  2. 前端使用多线程一块一块上传,上传前给服务器发一个消息校验该分块是否上传,如果已经上传则不再上传
  3. 等所有分块上传完毕,服务端合并所有分块,校验文件的完整性(因为分块全部上传到了服务器器,服务器所有分块按顺序进行合并,就是写每个分块文件内容按顺序依次写入一个文件中,使用字节流去读写文件)
  4. 前端给服务传了一个md5值,服务端合并文件后计算合并文件的md5是否和前端传的一样,如果一样则说明文件完整,如果不一样说明可能由于网络丢包导致文件不完整,这是上传失败需要重新上传
  5. 分块文件清理?
    上传一个文件进行分块上传,上传一般不传了,之前上传到minio的分块文件要清理吗?怎么做的?
  • 在数据库中有一张表表记录minio中存储的文件信息
  • 文件开始上传时会写入文件表,状态为上传中,上传完成会更新状态为上传完成
  • 当一个文件传了一般不再上传了说明该文件没有上传完成,会有定时任务去查询文件表中的记录,如果文件未上传完成则删除minio中没有上传成功的文件目录

一文搞懂分片上传和断点续传(代码片段)

...学问遗无力,少壮功夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这两种上... 查看详情

一文搞懂分片上传和断点续传(代码片段)

...学问遗无力,少壮功夫老始成〞一文搞懂分片上传和断点续传,对于做过文件上传的小伙伴对于这两个名词并不太陌生,而在上传大文件的业务中,这两种上传方式是经常被用到的,但是很多小白对这两种上... 查看详情

前端+后端实现分片上传(断点续传/极速秒传)(代码片段)

...后端(java)代码前端+后端实现分片上传(断点续传/极速秒传)前端slice分片上传,后端用表记录分片索引和分片大小和分片总数,当接受完最后一个分片(分片索引等于分片总数,分片索引从1... 查看详情

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

​需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制。第一步:前端修改由于项目使用的是BJUI前端框架,并... 查看详情

csharp文件分片上传,断点续传

需求:项目要支持大文件上传功能,经过讨论,初步将文件上传大小控制在500M内,因此自己需要在项目中进行文件上传部分的调整和配置,自己将大小都以501M来进行限制。 第一步:前端修改由于项目使用的是BJUI前端框架,... 查看详情

java如何实现大文件分片上传,断点续传和秒传

...思路前置知识源码参考引言关于文件上传模块,主要难点还是集中在大文件上传,毕竟我们无法确保在一个http连接中,能够将一个大文件完整传输过来,特别是在网络环境不稳定的情况下,如果是这样的话... 查看详情

springboot分片上传断点续传大文件极速秒传功能,这篇都帮你搞定!(典藏版)...(代码片段)

...上传网络环境环境不好,存在需要重传风险的场景2.断点续传2.1什么是断点续传断点续传是在下载或上传时,将下载或上传任务(一个文件或一个压缩包)人为的划分为几个部分,每一个部分采用一个线程进行... 查看详情

ios大文件分片上传和断点续传

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情

超大文件上传和断点续传的源代码

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情

大文件分片上传,断点续传,秒传实现

前段时间做视频上传业务,通过网页上传视频到服务器。视频大小小则几十M,大则1G+,以一般的HTTP请求发送数据的方式的话,会遇到的问题:1,文件过大,超出服务端的请求大小限制;2,请求时间过长,请求超时;3,传输中... 查看详情

vue超大文件上传解决方案:分片断点上传

...辑 文件块保存逻辑如下 web.xml配置如下 整个项目的截图 依赖的JAR包如下 运行效果如下: 在此分享!希望多多指正~后端代码逻辑大部分是相同的,目前能够支持MySQL,Oracle,SQL。在使用前需要配置一下数据库... 查看详情

前端实现大文件上传分片上传断点续传

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情

阿里云oss文件上传(分片上传断点续传)前后端实现(代码片段)

转载地址:https://segmentfault.com/a/1190000020963346         关于阿里云OSS的介绍请参考官方文档:阿里云OSS。出于账号安全的考虑,前端使用OSS服务需要走临时授权,即拿一个临时凭证(STSToken)去调用aliyun... 查看详情

阿里云oss文件上传(分片上传断点续传)前后端实现(代码片段)

转载地址:https://segmentfault.com/a/1190000020963346         关于阿里云OSS的介绍请参考官方文档:阿里云OSS。出于账号安全的考虑,前端使用OSS服务需要走临时授权,即拿一个临时凭证(STSToken)去调用aliyun... 查看详情

超大文件上传和断点续传的源代码

总结一下大文件分片上传和断点续传的问题。因为文件过大(比如1G以上),必须要考虑上传过程网络中断的情况。http的网络请求中本身就已经具备了分片上传功能,当传输的文件比较大时,http协议自动会将文件切片(分块)... 查看详情

如何实现大文件上传:秒传断点续传分片上传(代码片段)

前言文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进行上传,这可不是一个好的办法,毕竟很少有... 查看详情

如何实现大文件上传:秒传断点续传分片上传(代码片段)

前言文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进行上传,这可不是一个好的办法,毕竟很少有... 查看详情

10g大文件上传最全方案:秒传断点续传分片上传,包教会!

上一篇:麻了!Fastjson再曝反序列化漏洞。。前言文件上传是一个老生常谈的话题了,在文件相对比较小的情况下,可以直接把文件转化为字节流上传到服务器,但在文件比较大的情况下,用普通的方式进... 查看详情