Go语言模拟文件断点续传以及多协程读取写入文件操作

今天整理了一个Go语言多协程拷贝文件的案例,之前用Java写过,这次用Go语言来写一下,代码不难,也很简单,但是网上没有案例,整了很长时间。下面贴出来,供其他人参考学习。

func main(){

        fileName := "F:\\myWorks\\丽君-全家福.png"
        desfileName := "F:\\myWorks\\丽君-全家福-bak.png"
        sfile,err := os.Open(fileName)
        if err != nil{
                fmt.Println(nil)
        }

  
        info,_ := os.Stat(fileName)
        size := info.Size()
        var scount  int64 = 1
    //这里切分原意为通过协程来分段读取
        if size % 2 == 0{
                scount *= 2
        }else if size % 3 == 0 {
                scount *= 3
        }else{
                scount *= 1
        }
        si := size / scount
        fmt.Printf("文件总大小:%v, 分片数:%v,每个分片大小:%v",size,scount,si)

        desF,err := os.OpenFile(desfileName,os.O_CREATE|os.O_RDONLY|os.O_APPEND,0755)
        if err != nil{
                fmt.Println(err)
        }

        for i:=0;i<=int(scount);i++{
                        //申明一个byte
                        b := make([]byte,si)
                        //从哪个位置开始读
                        sfile.Seek(int64(i)*si,0)
                        //读到byte数组里边
                        sfile.Read(b)
                        //从哪个位置开始写
                        desF.Seek(int64(i)*si,0)
                        //写入
                        desF.Write(b)
        }

        defer desF.Close()
        defer sfile.Close()
}

上面的版本是一个按顺序写入的,虽然说是分片了但还是单协程,接下来改造一个多协程版本的。

func main(){

        fileName := "F:\\myWorks\\首页_1.png"
        desfileName := "F:\\myWorks\\首页_1-bak.png"
        sfile,err := os.Open(fileName)
        if err != nil{
                fmt.Println(nil)
        }

        info,_ := os.Stat(fileName)
        size := info.Size()
        var scount  int64 = 1
        if size % 2 == 0{
                scount *= 2
        }else if size % 3 == 0 {
                scount *= 3
        }else{
                scount *= 1
        }

        si := size / scount
        fmt.Printf("文件总大小:%v, 分片数:%v,每个分片大小:%v\n",size,scount,si)

        desF,err := os.OpenFile(desfileName,os.O_CREATE|os.O_RDWR,0755)
        if err != nil{
                fmt.Println(err)
        }

        for i:=0;i<int(si);i++{
                go func(vs int){
                        //申明一个byte
                        b := make([]byte,si)
                        //从指定位置开始读
                        sfile.ReadAt(b,int64(vs)*si)
                        //从指定位置开始写
                        desF.WriteAt(b,int64(vs)*si)

                }(i)
        }
        time.Sleep(time.Second*5)
        defer desF.Close()
        defer sfile.Close()
}

有问题可以在下方评论,技术问题可以私聊我。