go 下载文件增加进度条

方式1: 在writer层进行增加功能


var (
	GOOGLE_APPLICATION_CREDENTIALS = "/gcs.json"
)

type Writer struct {
	total   int64
	current int64
}

//没用到
func (w *Writer) getFileSize(bucket string, object string) {
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*10)
	defer cancel()

	o := client.Bucket(bucket).Object(object)
	attrs, _ := o.Attrs(ctx)
	w.total = attrs.Size

}

func (w *Writer) Write(b []byte) (n int, err error) {
	length := len(b)
	w.current += int64(length)
	w.PrintProgress()
	return length, nil
}

func (w *Writer) PrintProgress() {

	// Return again and print current status of download
	// We use the humanize package to print the bytes in a meaningful way (e.g. 10 MB)
	fmt.Printf("\rDownloading... %0.2f%% complete", float64(w.current*100)/float64(w.total))
}

func downloadFileWithProgress(w io.Writer, bucket, object string, destFileName string) error {
	ctx := context.Background()
	client, err := storage.NewClient(ctx)
	if err != nil {
		return fmt.Errorf("storage.NewClient: %v", err)
	}
	defer client.Close()

	ctx, cancel := context.WithTimeout(ctx, time.Second*6000)
	defer cancel()

	f, err := os.Create(destFileName)
	if err != nil {
		return fmt.Errorf("os.Create: %v", err)
	}

	rc, err := client.Bucket(bucket).Object(object).NewReader(ctx)
	if err != nil {
		return fmt.Errorf("Object(%q).NewReader: %v", object, err)
	}
	defer rc.Close()

	writer := &Writer{total: rc.Attrs.Size}
        //TeeReader()函数用于返回“Reader”,该“Reader”从声明的“r”读取,然后将其写入声明的“w”。
        //将通过声明的“r”执行的所有读取与对声明的“w”的等效写入进行比较。此方法不需要任何内部缓冲
        //并且读取完成后即可完成写入
	if _, err := io.Copy(f, io.TeeReader(rc, writer)); err != nil {
		return fmt.Errorf("io.Copy: %v", err)
	}

	if err = f.Close(); err != nil {
		return fmt.Errorf("f.Close: %v", err)
	}

	fmt.Fprintf(w, "Blob %v downloaded to local file %v\n", object, destFileName)

	return nil

}
// 环境变量设置
func init() {
	pwd, err := os.Getwd()
	if err != nil {
		panic(err)
	}
	os.Setenv("GOOGLE_APPLICATION_CREDENTIALS", {env})
}

func main() {
	err := downloadFileWithProgress(os.Stdout, "{gcs-bucketname}", "test01.csv", "./test01.csv")
	if err != nil {
		panic(err)
	}
}

效果:

方式二:在reader侧增加功能

todo

posted @ 2022-08-01 17:17  焦耳|程  阅读(256)  评论(0编辑  收藏  举报