目录


golang协程

golang协程分段下载文件,为了提升性能,更好的利用golang协程的特性,我们开始使用他测试一下我们的程序

golang协程方法能够提高处理性能,大家使用WaitGroup的时候记得要回收所有协程,也可以增加文件资源锁,防止文件上传失败,自己加吧

加锁示例
//定义锁
var reMu sync.Mutex

    
//处理返回数据
reMu .Lock()
rePath = append(Path, filePath)
reMu .Unlock()
golang协程分段下载文件 
/*
*
* 需求:
1. 多协程下载文件
2.断点续连
*
*/
func Coprogram(c *gin.Context) {
   //获取要下载文件
   DownloadFileName := "./123.zip"
   //copy的文件
   copyFileName := "./test.zip"
   storgeFileName := "./current.txt"
   //打开文件
   sfile, err := os.Open(DownloadFileName)
   if err != nil {
      fmt.Println(err)
   }
   defer sfile.Close()
   //获取文件大小
   info, _ := sfile.Stat()
   downloadSize := info.Size()
   var scount int64 = 1
   if downloadSize%5 == 0 {
      scount *= 5
   } else {
      scount *= 10
   }
   //分给每个协程的大小
   si := downloadSize / scount
   fmt.Printf("文件总大小:%v, 分片数:%v,每个分片大小:%v\n", downloadSize, scount, si)
   //open copy file
   copyFile, err := os.OpenFile(copyFileName, os.O_CREATE|os.O_WRONLY, os.ModePerm)
   if err != nil {
      fmt.Println(err)
   }
   storgeFile, err := os.OpenFile(storgeFileName, os.O_CREATE|os.O_RDWR, os.ModePerm)
   if err != nil {
      fmt.Println(err)
   }
   defer copyFile.Close()

   var currentIndex int64 = 0
   wg := sync.WaitGroup{}
   fmt.Println("协程进度条")
   pgb := pgbar.New("")
   for ; currentIndex < scount; currentIndex++ {//有多少个循环就开启多少个协程
      wg.Add(1)
      go func(current int64) {//定义一个匿名方法处理你需要协程处理的业务逻辑
         p := pgb.NewBar(fmt.Sprint((current+1))+"st", int(si))
         // p.SetSpeedSection(900, 100)
         b := make([]byte, 1024)
         bs := make([]byte, 16)
         currentIndex, _ := storgeFile.ReadAt(bs, current*16)
         //取出所有整数
         reg := regexp.MustCompile(`\d+`)
         countStr := reg.FindString(string(bs[:currentIndex]))
         total, _ := strconv.ParseInt(countStr, 10, 0)
         progressBar := 1
         for {
            if total >= si {
               wg.Done()//结束当前协程
               break
            }
            //从指定位置开始读
            n, err := sfile.ReadAt(b, current*si+total)
            if err == io.EOF {
               wg.Done()
               break
            }
            //从指定位置开始写
            copyFile.WriteAt(b, current*si+total)
            storgeFile.WriteAt([]byte(strconv.FormatInt(total, 10)+" "), current*16)
            total += int64(n)
            if total >= si/10*int64(progressBar) {
               progressBar += 1
               p.Add(int(si / 10))
            }

         }

      }(currentIndex)
   }
   wg.Wait()//协程等待
   storgeFile.Close()
   os.Remove(storgeFileName)
   fmt.Println("下载完成")
}