golang跨平台线程安全进度条显示插件progressbar的使用

Golang跨平台线程安全进度条显示插件progressbar的使用

progressbar是一个非常简单且线程安全的进度条库,可以在所有操作系统上正常工作。

安装

go get -u github.com/schollz/progressbar/v3

基本用法

// 创建一个默认进度条,总进度为100
bar := progressbar.Default(100)
for i := 0; i < 100; i++ {
    // 每次增加1个进度
    bar.Add(1)
    time.Sleep(40 * time.Millisecond)
}

I/O操作

progressbar实现了io.Writer接口,因此可以自动检测写入流的字节数,你可以将其用作io.Reader的进度条。

// 下载文件示例
req, _ := http.NewRequest("GET", "https://dl.google.com/go/go1.14.2.src.tar.gz", nil)
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()

f, _ := os.OpenFile("go1.14.2.src.tar.gz", os.O_CREATE|os.O_WRONLY, 0644)
defer f.Close()

// 创建基于字节的进度条
bar := progressbar.DefaultBytes(
    resp.ContentLength,  // 总字节数
    "downloading",       // 进度条描述
)
// 将数据同时写入文件和进度条
io.Copy(io.MultiWriter(f, bar), resp.Body)

未知长度的进度条

当进度条长度为-1时,它会自动转换为带有可自定义旋转器类型的旋转动画。

// 将resp.ContentLength设置为-1即可创建旋转动画
bar := progressbar.DefaultBytes(-1, "processing")

自定义

你可以进行大量自定义 - 更改写入器、颜色、宽度、描述、主题等。

bar := progressbar.NewOptions(1000,
    progressbar.OptionSetWriter(ansi.NewAnsiStdout()), // 需要安装"github.com/k0kubun/go-ansi"
    progressbar.OptionEnableColorCodes(true),          // 启用颜色代码
    progressbar.OptionShowBytes(true),                 // 显示字节数
    progressbar.OptionSetWidth(15),                    // 设置宽度
    progressbar.OptionSetDescription("[cyan][1/3][reset] Writing moshable file..."), // 设置描述
    progressbar.OptionSetTheme(progressbar.Theme{      // 自定义主题
        Saucer:        "[green]=[reset]",             // 进度条填充字符
        SaucerHead:    "[green]>[reset]",             // 进度条头部字符
        SaucerPadding: " ",                           // 进度条填充
        BarStart:      "[",                           // 进度条开始字符
        BarEnd:        "]",                           // 进度条结束字符
    }))
for i := 0; i < 1000; i++ {
    bar.Add(1)
    time.Sleep(5 * time.Millisecond)
}

完整示例

下面是一个完整的示例,展示了progressbar的基本用法和自定义选项:

package main

import (
	"io"
	"net/http"
	"os"
	"time"

	"github.com/k0kubun/go-ansi"
	"github.com/schollz/progressbar/v3"
)

func main() {
	// 示例1: 基本进度条
	basicExample()

	// 示例2: 下载文件进度条
	downloadExample()

	// 示例3: 自定义进度条
	customExample()
}

func basicExample() {
	// 创建一个默认进度条,总进度为100
	bar := progressbar.Default(100)
	for i := 0; i < 100; i++ {
		// 每次增加1个进度
		bar.Add(1)
		time.Sleep(40 * time.Millisecond)
	}
}

func downloadExample() {
	// 下载文件示例
	req, _ := http.NewRequest("GET", "https://dl.google.com/go/go1.14.2.src.tar.gz", nil)
	resp, _ := http.DefaultClient.Do(req)
	defer resp.Body.Close()

	f, _ := os.OpenFile("go1.14.2.src.tar.gz", os.O_CREATE|os.O_WRONLY, 0644)
	defer f.Close()

	// 创建基于字节的进度条
	bar := progressbar.DefaultBytes(
		resp.ContentLength,  // 总字节数
		"downloading",       // 进度条描述
	)
	// 将数据同时写入文件和进度条
	io.Copy(io.MultiWriter(f, bar), resp.Body)
}

func customExample() {
	// 自定义进度条示例
	bar := progressbar.NewOptions(1000,
		progressbar.OptionSetWriter(ansi.NewAnsiStdout()),
		progressbar.OptionEnableColorCodes(true),
		progressbar.OptionShowBytes(true),
		progressbar.OptionSetWidth(15),
		progressbar.OptionSetDescription("[cyan][1/3][reset] 处理中..."),
		progressbar.OptionSetTheme(progressbar.Theme{
			Saucer:        "[green]=[reset]",
			SaucerHead:    "[green]>[reset]",
			SaucerPadding: " ",
			BarStart:      "[",
			BarEnd:        "]",
		}))
	for i := 0; i < 1000; i++ {
		bar.Add(1)
		time.Sleep(5 * time.Millisecond)
	}
}

progressbar库提供了简单易用的API,可以轻松地在Golang应用中添加进度条功能,支持跨平台使用且线程安全。


更多关于golang跨平台线程安全进度条显示插件progressbar的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang跨平台线程安全进度条显示插件progressbar的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


Golang跨平台线程安全进度条插件progressbar使用指南

progressbar是一个简单易用的Golang进度条库,支持跨平台显示,并且是线程安全的。下面我将详细介绍它的使用方法。

安装

go get github.com/schollz/progressbar/v3

基本使用

package main

import (
	"time"
	"github.com/schollz/progressbar/v3"
)

func main() {
	// 创建一个总数为100的进度条
	bar := progressbar.Default(100)
	
	for i := 0; i < 100; i++ {
		time.Sleep(100 * time.Millisecond)
		// 增加进度
		bar.Add(1)
	}
}

自定义进度条

progressbar提供了丰富的自定义选项:

bar := progressbar.NewOptions(100,
	progressbar.OptionSetWriter(os.Stderr),
	progressbar.OptionEnableColorCodes(true),
	progressbar.OptionSetWidth(50),
	progressbar.OptionSetDescription("[cyan][1/3][reset] 处理文件..."),
	progressbar.OptionSetTheme(progressbar.Theme{
		Saucer:        "[green]=[reset]",
		SaucerHead:    "[green]>[reset]",
		SaucerPadding: " ",
		BarStart:      "[",
		BarEnd:        "]",
	}),
)

线程安全使用

progressbar本身就是线程安全的,可以在goroutine中使用:

func worker(id int, bar *progressbar.ProgressBar, wg *sync.WaitGroup) {
	defer wg.Done()
	
	for i := 0; i < 25; i++ {
		time.Sleep(time.Duration(rand.Intn(100)) * time.Millisecond)
		bar.Add(1) // 线程安全地增加进度
	}
}

func main() {
	bar := progressbar.Default(100)
	var wg sync.WaitGroup
	
	for i := 0; i < 4; i++ {
		wg.Add(1)
		go worker(i, bar, &wg)
	}
	
	wg.Wait()
}

高级功能

1. 动态描述

bar := progressbar.NewOptions(100,
	progressbar.OptionOnCompletion(func() {
		fmt.Fprint(os.Stderr, "\n")
	}),
	progressbar.OptionSetRenderBlankState(true),
)

for i := 0; i < 100; i++ {
	bar.Set(i) // 直接设置进度
	bar.Describe(fmt.Sprintf("处理第 %d 项", i))
	time.Sleep(50 * time.Millisecond)
}

2. 文件下载进度条

resp, _ := http.Get("https://example.com/largefile.zip")
defer resp.Body.Close()

f, _ := os.OpenFile("largefile.zip", os.O_CREATE|os.O_WRONLY, 0644)
defer f.Close()

bar := progressbar.DefaultBytes(
	resp.ContentLength,
	"下载中",
)
io.Copy(io.MultiWriter(f, bar), resp.Body)

3. 多进度条

// 第一个进度条
bar1 := progressbar.NewOptions(100,
	progressbar.OptionSetDescription("任务1"),
	progressbar.OptionSetWriter(os.Stderr),
)

// 第二个进度条
bar2 := progressbar.NewOptions(100,
	progressbar.OptionSetDescription("任务2"),
	progressbar.OptionSetWriter(os.Stderr),
	progressbar.OptionClearOnFinish(),
)

go func() {
	for i := 0; i < 100; i++ {
		time.Sleep(100 * time.Millisecond)
		bar1.Add(1)
	}
}()

for i := 0; i < 100; i++ {
	time.Sleep(150 * time.Millisecond)
	bar2.Add(1)
}

注意事项

  1. 在Windows上可能需要启用VT100终端支持:

    progressbar.OptionSetWriter(ansi.NewAnsiStdout())
    
  2. 如果进度条显示不正常,可以尝试:

    progressbar.OptionUseANSICodes(true)
    
  3. 在Docker或CI环境中使用时,可能需要禁用进度条:

    if !isTerminal {
        progressbar.OptionSetWriter(io.Discard)
    }
    

progressbar库简单易用且功能强大,非常适合在命令行工具中显示进度信息。它的线程安全特性使其可以安全地在并发环境中使用。

回到顶部