文件分块与断点续传还不会?一文告诉你设计思路

257 阅读5分钟

文件分块上传

实现大文件的分块上传功能涉及前端、后端(Java)以及数据库的协同工作。这个功能的核心在于将大文件分割成多个小块,分别上传,然后在服务器端重新组合这些块。以下是一个基本的设计思路:

前端设计

  1. 文件选择与分块
  • 用户通过界面选择要上传的大文件。
  • 使用 JavaScript 将文件分割成多个小块,通常使用Blob.slice() 方法。
  1. 显示上传进度
  • 为每个文件块提供一个上传进度条。
  • 实时显示每个块的上传状态。
  1. 并发上传块
  • 使用异步请求(如fetchXMLHttpRequest)并发上传各个块。
  • 可以设置并发数量限制,以防止过多的并发请求。
  1. 错误处理与重试
  • 为每个上传失败的块提供重试机制。
  • 可以设置重试次数限制。

后端设计

  1. 接收文件块
  • 创建一个接口来接收文件块。这个接口应该能处理多部分(multipart)请求。
  • 提取文件块及其元信息(如块编号、文件ID等)。
  1. 文件块存储
  • 暂时将接收到的文件块存储在服务器的文件系统或临时存储中。
  • 确保文件块有唯一标识,以便最后重组。
  • 这里的重组可以考虑在OSS或者自己搭建的MinIO集群中进行,以目录的方式,将所有的文件快存放到某一个目录下。
  1. 数据库记录
  • 使用数据库记录每个文件的上传状态,包括已上传的块、总块数、文件大小等。
  • 可以为每个文件块存储校验和以确保数据完整性。
  1. 文件块重组
  • 当所有块都上传完成后,后端程序将这些块按照顺序重组成完整的文件。
  • 重组可以考虑使用定时任务扫库的方式来进行重组。
  • 验证重组后文件的完整性。
  1. 错误处理
  • 提供错误信息给前端,例如哪个块上传失败。
  • 实现异常处理机制。

数据库设计

  1. 文件表
  • 存储文件的元数据,如文件名、总大小、状态(如上传中、完成、错误)、创建和完成时间等。
  1. 文件块表
  • 存储每个文件块的信息,如所属文件ID、块序号、大小、存储位置、校验和、状态等。
  1. 关系设计
  • 文件表与文件块表通过文件ID关联。
  • 确保数据结构支持快速查询和更新。

安全性考虑

  1. 身份验证和授权
  • 确保只有授权用户可以上传文件
  • 对上传接口进行身份验证
  1. 数据传输安全
  • 使用 Https 来进行加密数据传输
  • 为文件块添加签名,确保传输安全性
  1. 防止攻击
  • 限制传输的速率和传输文件的大小,防止恶意上传
  • 对上传的文件进行扫描,检查是否安全

文件断点续传

实现断点续传功能主要涉及到在上传过程中跟踪已上传的文件块,并在上传中断后能够从上次中断的位置继续上传。这需要在前端、后端以及数据库中都做相应的处理。

前端设计

  1. 记录已经上传的文件块
  • 在上传每个块之前,检查该块是否已经上传(可能是之前的尝试)。
  • 可以通过本地存储(如LocalStorage)来记录每个文件块的上传状态。
  1. 恢复上传
  • 当用户重新开始上传时(或在上传页面刷新后),前端应该能够读取之前上传的状态。
  • 根据记录的状态,跳过已经上传的块,只上传剩余的块。

后端设计

  1. 检查文件块的状态
  • 在接收到一个文件块时,首先检查该块是否已经存在或已上传(可以考虑 MD5 来实现)。
  • 通过查询数据库来实现,检查该文件的特定块是否已被记录为上传。
  1. 处理重复上传
  • 如果收到的块已经上传过,可以简单地忽略重复上传的块,或者更新已有块的信息(如校验和)。
  1. 支持部分上传
  • 后端 API 应该能够处理部分上传的文件,即接受并存储只上传了部分块的文件。

数据库设计

  1. 跟踪文件状态
  • 在文件块表中,为每个块增加状态字段,如“未上传”、“上传中”、“已上传”。
  • 记录每个块的上传时间,以便于处理过期的部分上传文件。
  1. 处理中断和恢复
  • 为支持断点续传,数据库应该能够快速查询到每个文件的上传状态,包括已上传和未上传的块。

安全性考虑

  1. 校验和验证
  • 在文件块上传完成后,可以对每个块使用校验和来验证其完整性(可以考虑使用 CRC 16)。
  • 当所有块都上传并组装成完整文件后,需要再次验证整个文件的完整性。
  1. 清除机制
  • 对于长时间未完成的部分上传文件,实施定期清理策略。
  • 为避免资源浪费,可以定期清除那些长时间未被完成的上传文件和块。