golang实现文件上传(高并发+分块+断点续传+加密)

运行视频

// 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,开发语言,后端)