当前位置:网站首页>分布式文件存储——文件秒传
分布式文件存储——文件秒传
2022-08-08 21:09:00 【~庞贝】
实现文件秒传
文件的校验值计算
校验算法类型 校验码长度
1.CRC 4/8字节 计算效率高但安全性较低 传输数据的校验
2.MD5 16个字节 中等 文件校验和数据签名
3.SHA1 20个字节 安全性高 文件校验和数据签名
场景
1.用户上传
2.离线下载
3.好友分享
关键点
1.文件的Hash值(MD5,Sha1)
每次文件上传到云存储服务,会自动计算文件的HASH值,下一次用户上传,只要Hash值相同就可以省区重复上传,客户端计算文件Hash值传到云端进行对比才可以实现秒传
2.用户文件的关联
建立唯一文件表用于存储唯一的文件的信息,而用户文件表存储每个用户的文件的信息,包括重复文件
文件秒传服务架构
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2npiPqgx-1659837717597)(C:/Users/86158/AppData/Roaming/Typora/typora-user-images/image-20220807095740398.png)]](/img/86/d9086e10181c58f64bf22de83971f6.png)
如图
- 用户上传文件到上传server
- 上传server将文件存储到本地
- 调用Hash计算文件Hash值
- 将文件信息存储到唯一文件表
- 将文件信息关联到用户文件表
如果计算出文件Hash值比对成功则减少上传实现秒传
在db/下创建db/userFile,并创建用户文件结构体和用户文件表的更新
import (
mydb "rgo/src/db/mysql"
"time"
)
//用户文件表的结构体
type UserFile struct{
UserName string
FileHash string
FileName string
FileSize int64
UploadAt string
LastUpdated string
}
//更新用户文件表
func OnUserFileUploadFinished(username,filehash,filename string,filesize int64)bool{
stmt,err:=mydb.DBConn().Prepare("" +
"insert ignore into tbl_user_file(`user_name`,`file_sha1`,`file_name`,"+
"`file_size`,`upload_at`)values(?,?,?,?,?)")
if err!=nil{
return false
}
defer stmt.Close()
_,err=stmt.Exec(username,filehash,filename,filesize,time.Now())
if err!=nil{
return false
}
return true
}
在handler/handler.go的UploadHandler中修改
//更新用户文件表记录
r.ParseForm()
username := r.Form.Get("username")
suc := dblayer.OnUserFileUploadFinished(username, fileMeta.FileShal,
fileMeta.FileName, fileMeta.FileSize)
if suc {
http.Redirect(w, r, "/file/upload/suc", http.StatusFound)
} else {
w.Write([]byte("Upload Failed"))
}
db/userFile下创建函数
//批量获取用户文件信息
func QueryUserFileMetas(username string,limit int)([]UserFile,error){
stmt,err:=mydb.DBConn().Prepare(
"select file_sha1,file_name,file_size,upload_at,last_update from"+
"tbl_user_file where user_name=? limit ?")
if err!=nil{
return nil,err
}
defer stmt.Close()
rows,err:=stmt.Query(username,limit)
if err!=nil{
return nil,err
}
var userFiles []UserFile
for rows.Next(){
//从数据库查找的表中将文件信息复制到[]UserFile作为返回
ufile:=UserFile{
}
err=rows.Scan(&ufile.FileHash,&ufile.FileName,&ufile.FileSize,
&ufile.UploadAt,&ufile.LastUpdated)
if err!=nil{
fmt.Println(err.Error())
break
}
userFiles=append(userFiles,ufile)
}
return userFiles,nil
}
在handler/handler.go修改接口
//查询批量的文件元信息
func FileQueryHandler(w http.ResponseWriter,r*http.Request){
r.ParseForm()
limitCnt,_:=strconv.Atoi(r.Form.Get("limit"))
username:=r.Form.Get("username")
userFiles,err:=dblayer.QueryUserFileMetas(username,limitCnt)
if err!=nil{
w.WriteHeader(http.StatusInternalServerError)
return
}
data,err:=json.Marshal(userFiles)
if err!=nil{
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Write(data)
}
在handler/handler.go中编写
//尝试秒传接口
func TryFastUploadHandler(w http.ResponseWriter,r*http.Request){
r.ParseForm()
//1.解析请求参数
username:=r.Form.Get("username")
filehash:=r.Form.Get("filehash")
filename:=r.Form.Get("filename")
filesize,_:=strconv.Atoi(r.Form.Get("filesize"))
//从文件表中查询相同hash文件记录
fileMeta,err:=meta.GetFileMetaDB(filehash)
if err!=nil{
fmt.Println(err.Error())
w.WriteHeader(http.StatusInternalServerError)
return
}
//查找不到记录则返回秒传失败
if fileMeta==nil{
resp:=util.RespMsg{
Code:-1,
Msg:"秒传失败,请访问普通上传接口",
}
w.Write(resp.JSONBytes())
return
}
//上传文过件则将文件信息写入用户文件表,返回成功
suc:=dblayer.OnUserFileUploadFinished(username,filehash,filename,int64(filesize))
if suc{
resp:=util.RespMsg{
Code:0,
Msg:"秒传成功",
}
w.Write(resp.JSONBytes())
return
}else{
resp:=util.RespMsg{
Code:-2,
Msg:"秒传失败,请稍后重试",
}
w.Write(resp.JSONBytes())
return
}
}
边栏推荐
- MySQL无法启用/etc/my.cnf配置文件,重启报错Warning: World-writable config file ‘/etc/my.cnf’ is ignored的解决方法
- EasyExcel上传文件并使用Postman测试
- day3 Feign远程调用
- selenium基本使用
- IDEA Error:(1, 1) 错误: 非法字符: \65279 Error:(1, 10) 错误: 需要class, interface或enum 解决办法
- mysql8设置远程连接
- 图神经网络GNN简介及应用方向
- The access to the local projects, localhosthost can, local IP can't 】
- sudo控制用户权限实战操作
- C#实现Everything——UI与查询 附源码
猜你喜欢

微信小程序--》数据请求和页面导航
Getting Started with GeoServer: 04-Publishing Shapfile Map Data

Everything原理探究以及C#实现

数组的push()、pop()、shift()和unshift()方法讲解

阿里云祝顺民:算力网络架构的新探索
GeoServer入门学习:03-快速入门

单片机--IIC总线篇

C#实现Everything——UI与查询 附源码

神经网络论文Enhancing deep neural networks via multiple kernel learning

去噪论文 Attention-Guided CNN for Image Denoising
随机推荐
蚂蚁感冒,蓝桥杯,简易AC代码讲解
去噪论文 Attention-Guided CNN for Image Denoising
安全策略及电商购物订单简单用例
目标检测论文 Precise detection of Chinese characters in historical documents with DRL
ES6新特性let和const
rancher -部署
js写一个气泡屏保能碰撞
图像噪声水平估计INLE_paper
小程序-按钮透明无边框
两个行间块状div之间的间隙消除
numpy基础
全国基础地理数据库数据预处理
Under the Windows socket (TCP) console program
[MEF]第04篇 MEF的多部件导入(ImportMany)和目录服务
单片机——串口通信(从串口接收多位数据保存到数组,发送多位数据到串口)
js写一个搜索添加记录,点击记录删除内容
二分、前缀和(激光炸弹)几道例题的详细讲解,帮助理解相关知识点
charles简单使用
a标签的三种禁止跳转方式
GeoServer Getting Started Learning: 06-Publishing Multi-level TIF Map Data