golang 并发传文件 --服务端

package main

import (
   "archive/zip"
   "fmt"
   "io"
   "math"
   "net"
   "os"
   "path"
   "strconv"
)

const chunkSize = 1 * 30 << (10 * 2)

//const fileName = "putty.exe"
const port = 40000

var zipName = "cbd88.zip"

func main() {
   wd, _ := os.Getwd()
   fmt.Println(wd)
   srcDir, err := os.OpenFile(wd, os.O_RDONLY, os.ModePerm)
   defer srcDir.Close()
   if err != nil {
      panic(err)
   }
   names, err := srcDir.Readdirnames(1000)
   if err != nil {
      panic(err)
   }
   fmt.Println(names)

   zipfile, err := os.Create(zipName)
   if err != nil {
      panic(err)
   }
   defer zipfile.Close()

   archive := zip.NewWriter(zipfile)

   for _, name := range names {
      if name == "." || name == "server.exe" || name == zipName {
         continue
      }

      file, err := os.Open(name)
      if err != nil {
         panic(err)
      }
      defer file.Close()

      err = compress(file, "", archive)
      if err != nil {
         panic(err)
      }

   }
   archive.Close()

   srcFile, err := os.OpenFile(zipName, os.O_RDONLY, os.ModePerm)
   defer srcFile.Close()
   if err != nil {
      panic(err)
   }
   fileInfo, err := srcFile.Stat()
   if err != nil {
      panic(err)
   }
   srcSize := fileInfo.Size()
   srcExt := path.Ext(zipName)

   num := math.Ceil(float64(srcSize) / chunkSize)

   //===========================
   for i := 1; i <= int(num); i++ {
      srcFile.Seek(int64((i-1)*chunkSize), 0)
      buf := make([]byte, chunkSize)

      if chunkSize > (int(srcSize) - chunkSize*(i-1)) {
         buf = make([]byte, int(srcSize)-chunkSize*(i-1))
      }
      _, err := srcFile.Read(buf)
      if err != nil {
         panic(err)
      }
      go startSer(i, &buf)

   }
   //===========================

   lastChunkSize := srcSize - chunkSize*(int64(num)-1)

   res := fmt.Sprint(port) + " " + fmt.Sprint(num) + " " + fmt.Sprint(chunkSize) + " " + fmt.Sprint(lastChunkSize) + " " + zipName + " " + srcExt
   fmt.Println(res)

   //for i := 1; i <= int(num); i++ {
   // go startSer(i)
   //}

   listener, err := net.Listen("tcp", ":40000")
   if err != nil {
      panic(err)
   }
   for {
      conn, err := listener.Accept()
      if err != nil {
         panic(err)
      }
      conn.Write([]byte(res))
   }

}

func startSer(i int, bytes *[]byte) {
   addrs := ":" + strconv.Itoa(port+i)

   listener, err := net.Listen("tcp", addrs)
   if err != nil {
      panic(err)
   }

   conn, err := listener.Accept()
   if err != nil {
      panic(err)
   }
   n, err := conn.Write(*bytes)
   if err != nil {
      panic(err)
   }
   if n != len(*bytes) {
      panic("长度不对")
   }
}

func compress(file *os.File, prefix string, zw *zip.Writer) error {
   info, err := file.Stat()
   if err != nil {
      return err
   }
   if info.IsDir() {
      if prefix == "" {
         prefix = info.Name()
      } else {
         prefix = prefix + "/" + info.Name()
      }
      fileInfos, err := file.Readdir(-1)
      if err != nil {
         return err
      }
      for _, fi := range fileInfos {
         f, err := os.Open(file.Name() + "/" + fi.Name())
         if err != nil {
            return err
         }
         err = compress(f, prefix, zw)
         if err != nil {
            return err
         }
      }
   } else {
      header, err := zip.FileInfoHeader(info)
      header.Method = zip.Deflate
      if prefix != "" {
         header.Name = prefix + "/" + header.Name
      }
      if err != nil {
         return err
      }
      writer, err := zw.CreateHeader(header)
      if err != nil {
         return err
      }
      _, err = io.Copy(writer, file)
      file.Close()
      if err != nil {
         return err
      }
   }
   return nil
}

转载于:https://my.oschina.net/wgc2010/blog/2875861

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值