yunlian-file-transfer-demo/client/client.go
2021-05-11 12:34:41 +08:00

130 lines
2.6 KiB
Go

/**
* 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
}