/** * Created by IntelliJ IDEA. * User: Ar.M * Date: 2020-05-10 * Time: 22:10 */ package main import ( "bytes" "context" "flag" "fmt" "github.com/dustin/go-humanize" "google.golang.org/grpc" "io" "log" "os" "strings" transportpb "yunlian-file-transfer-demo/proto" ) var ( fn *string ip *string port *int savePath *string ) func init() { fn = flag.String("fn", "", "文件名称") ip = flag.String("ip", "127.0.0.1", "服务端 IP 地址") port = flag.Int("port", 10086, "服务端端口号") savePath = flag.String("savepath", "./", "存储路径") flag.Usage = func() { fmt.Println("yunlian-file-transfer-demo version: 0.0.1") flag.PrintDefaults() } } func main() { flag.Parse() if len(*fn) < 1 { flag.Usage() return } requestedFile := *fn serverIp := fmt.Sprintf("%s:%d", *ip, *port) cc, err := grpc.Dial(serverIp, grpc.WithInsecure()) if err != nil { log.Fatalf("监听服务端异常 : %v\n", err) } defer cc.Close() c := transportpb.NewFileServiceClient(cc) if err := download(requestedFile, c); err != nil { log.Fatalf("下载异常 %s : %v\n", requestedFile, err) } fmt.Printf("\n%s 下载成功\n", requestedFile) } func writeFile(fileName string, content []byte) { if len(content) != 0 { fp, err := os.OpenFile(fileName, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0755) if err != nil { log.Fatalf("文件打开异常: %s\n", err) } defer fp.Close() _, err = fp.Write(content) if err != nil { log.Fatalf("文件保存异常: %s\n", err) } } } func getFileStat(fileName string) int64 { fileinfo, err := os.Stat(fileName) if err != nil { if os.IsNotExist(err) { return int64(0) } log.Fatalf("获取文件元数据失败: %s\n", err) } return fileinfo.Size() } func download(fileName string, client transportpb.FileServiceClient) error { fileRange := getFileStat(fileName) req := &transportpb.FileRequest{ FileName: fileName, FileRange: fileRange, } stream, err := client.Download(context.Background(), req) if err != nil { return err } var recvSize int64 var buffer bytes.Buffer recvSize = fileRange for { res, err := stream.Recv() if err == io.EOF { break } if err != nil { buffer.Reset() return err } block := res.GetBlock() fileSize := res.GetFileSize() blockSize := len(block) recvSize += int64(blockSize) writeFile(fileName, block) // fmt.Printf("\r%s", strings.Repeat(" ", 30)) fmt.Printf("\r文件%s: %s / %s 已下载%s", fileName, humanize.IBytes(uint64(recvSize)), humanize.IBytes(uint64(fileSize)), strings.Repeat(" ", 60)) } return nil }