Talk Is Cheap,Show Me The Code 大文件上传解决方案与实例代码

核心:

  • 分段接收,分段解析,分段写文件

问题

  • Q:不同用户上传同一文件:

    • A: 通过token加文件md5码解决,并且后期如果发现为同一文件甚至不需要上传,直接服务器cp一份
  • Q:同一个用户刷新上传(重复上传)

    • A:通过会话id (processId: 通过token+md5 生成,防止上传重复上传同一文件,碎片共享同一个processId) & 碎片状态化: 杜绝重复上传碎片,同时实现断点续传
      • Q: 为什么要token+md5
        • A: 可以防止如下
          • md5作用:防止A用户重复上传同一文件"
          • 防止A用户重复上传同一文件"
          • 防止A用户重复上传同一文件"
          • token:防止A用户上传的碎片 跑到B碎片上 (既A,B上传类似碎片或者同一视频)
      • Q: 碎片有哪些状态:
        • A: 传输失败 | 正在传输(因为是分段解析,所以会有中间状态) | 传输成功
      • Q: 碎片共享同一个processId会出现数据冗余吗:
        • A: 不会,processId并非uuid,只要是同一个文件以及同一个用户,必然相同
    • Q: processId谁颁发:
      • A: 前端颁发 | 后端颁发 ,延伸问题请看 进度条查询部分
  • Q: 进度条如何查询:

    • Q: 碎片进度查询:
      • A: 碎片有index(chunk)块的概念,缓存中存放了该碎片的总的容量,以及已经缓存的容量
        • Q: 需要携带的参数:
          • A: 文件的md5(非碎片的md5,在本处无碎片md5的概念) & 碎片的chunk (代表第几块)
            • 切片还是需要携带MD5,并且是自身的md5,因为 processId和chunk 并不能代表这个chunk,md5可以
            • Q: 如果 会话id是由服务器颁发 何时发起轮询请求:
              • A: 完美的方式是当服务端收到请求之后通过webSocket通知前端 你收到本次会话的id了,发起轮询吧 若不采用websocket,则只能前端携带uuid给后端后,后端存储k-v(key为uuid,value为会话id),前端通过uuid轮询服务器获取会话id ,所以 会话id还不如前端颁发
    • Q: 文件进度查询:
      • A: 已上传的部分累加 / 总数
    • Q: 碎片进度如何更新: 通过BufferedInputStream 分段读取每次请求的数据,之后更新到缓存中 (既 分段解析)
  • Q: 何时合并文件,既何时结束

    • A: 前端发起通知,后端开始合并碎片
      • Q: 能否后端主动发起合并: 本项目中自己自动合并
        • A: 可以,但是必须额外传递一个 总碎片数参数
          • 单文件形式: ,后端判断是否是最后一块
          • 多文件形式: 额外定义一个原子变量(可以优化到redis中)做累加,达到数目开启合并 ,但是必须要确保数据读取正确,不能有bab的问题,redis可以实现
    • Q: 如何合并,全部读取再加载到内存中?
      • WIP A: Java 暂时通过FileChannel实现
  • Q: 如何断点续传:

    • A: 服务端存储切片的唯一信息,写入的时候判断是否存在即可
  • Q: 如何分段写入到文件:

    • 通过randAccessFile
  • Q: 在上传途中,服务器宕机怎么办,确切点说既缓存碎片状态的服务器挂了,数据清空了(保存在内存中)

    • A: 既: 如果MD5等信息是存储在内存中,而磁盘碎片是存在的
      • 要么是传输中途断了,既失败了同时缓存也丢了-> 删除|清空
      • 要么是传输成功了,但是缓存丢了-> 依旧删除
      • 所以,缓存丢了就删除
  • Q: 当合并的时候,合并失败:

对象:

上传对象

  • chunk: 代表碎片下标

Talk is cheap , I am coding

  • DEMO
    • 更改文件名即可,支持进度展示,不需要sql,nosql
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值