// todo 根据前端传递文件加密
func (s *FileProcess) FileProcessEncryptionByFront(file multipart.File, h *multipart.FileHeader) interface{} { //根据字节直接处理文件 这个是前端传递的二进制流
s.FileProcessInit() //文件初始化 设置原来文件的缓冲区和加密缓冲区的字节大小
s.SourceFile.SetSize(int(h.Size)) //设置原文件的总字节
s.SourceFile.SetName(h.Filename) //设置原文件的名称
s.EncryptFile.SetName(h.Filename) //设置加密文件后的名称
filePath := s.EncryptFile.Name
save, _ := os.OpenFile(s.EncryptFile.Name, os.O_CREATE|os.O_RDWR, os.ModePerm) //打开加密文件
fileBool, err := isExists(filePath)
if fileBool && err == nil {
fmt.Println("文件已经存在")
} else {
newfile, err := os.Create(filePath) //创建当前文件
defer newfile.Close()
if err != nil {
fmt.Println("创建文件失败")
}
}
s.SetNumberDncrypted(s.SourceFile) //设置原文件的携程数量 因为是根据原文件加密
TODO block := head.Size / 5 //把数据分成五片 一般不建议这种方式 因为文件太大的话分的单位也会太大 使用这种方式 可以把一片大小理解成一个缓冲区
var wg sync.WaitGroup
for i := 0; i < s.NumberCoroutine; i++ {
wg.Add(1) //确保所有的文件合并
}
for i := 0; i < s.NumberCoroutine; i++ {
// if i != 3 && i != 6 { //模拟网络中断导致某个数据库块没有上传
go func(i int) {
defer wg.Done()
buf := make([]byte, s.SourceFile.BockByteNum) // 定义一个缓冲区,用于读取文件块数据
offset := i * s.SourceFile.BockByteNum
save_offset := i * s.EncryptFile.BockByteNum //todo 这部要注意 当前加密保存后文件的一个偏移量
bufSave := make([]byte, s.EncryptFile.BockByteNum) //加密保存文件的缓冲区不一样
_, err := save.ReadAt(bufSave, int64(save_offset)) //判断当前的文件偏移量是否有数据
if !(err != nil && err != io.EOF) { //如果没有数据
n1, err1 := file.ReadAt(buf, int64(offset)) //读取原来上传文件的完整数据
if err1 != nil && err1 != io.EOF {
panic(err1.Error())
}
byte1, _ := tool.Encrypt(buf[:n1]) //字节加密
_, err = save.WriteAt(byte1, int64(save_offset)) // 从偏移量处写入文件块数据
//
//if i == 0 {
// for i := 0; i < 10; i++ {
// fmt.Println("上传前100个原文", buf[i])
// }
//}
//if i == numThread-1 {
// //fmt.Println("最终转换字节数量为", len(getByte), "")
// for i := len(buf[:n1]) - 10; i < len(buf[:n1]); i++ {
// fmt.Println("上传原文最后十个字节数量为", buf[i])
// }
}
}(i)
}
wg.Wait()
//设置加密文件的缓冲区
return nil
}
golang实现文件上传(高并发+分块+断点续传+加密)
最新推荐文章于 2024-05-02 10:06:16 发布