golang通过URL从多种来源下载文件或目录的插件库go-getter的使用

go-getter 使用指南

go-getter 是一个 Go 语言库,用于通过 URL 从多种来源下载文件或目录。它的强大之处在于能够使用单个字符串作为输入从多种不同的来源(文件路径、Git、HTTP、Mercurial 等)下载内容,从而减轻了开发者需要了解如何从各种来源下载的负担。

安装和使用

可以通过正常的 go get 命令安装:

$ go get github.com/hashicorp/go-getter

go-getter 还提供了一个命令行工具,可以用来测试 URL 字符串:

$ go install github.com/hashicorp/go-getter/cmd/go-getter
...
$ go-getter github.com/foo/bar ./foo
...

基本使用示例

下面是一个使用 go-getter 下载文件的完整示例:

package main

import (
    "log"
    "github.com/hashicorp/go-getter"
)

func main() {
    // 定义下载源和目标路径
    src := "github.com/hashicorp/go-getter//testdata"
    dst := "./downloaded"
    
    // 创建客户端
    client := &getter.Client{
        Src:  src,
        Dst:  dst,
        Dir:  true,  // 下载目录
    }
    
    // 执行下载
    if err := client.Get(); err != nil {
        log.Fatalf("下载失败: %s", err)
    }
    
    log.Println("下载成功")
}

URL 格式

go-getter 使用单个字符串 URL 作为输入,支持多种协议和格式:

支持的协议和检测器

支持的协议包括:

  • 本地文件
  • Git
  • Mercurial
  • HTTP
  • Amazon S3
  • Google GCP

检测器可以自动将无效 URL 转换为适当的 URL。例如:

  • github.com/mitchellh/vagrant 会自动转换为 Git 协议
  • ./foo 会自动转换为文件 URL

强制协议

在某些情况下,源 URL 的协议不明确。可以使用双冒号强制指定协议:

src := "git::http://github.com/mitchellh/vagrant.git"

子目录下载

如果只想下载目录中的特定子目录,可以在双斜杠 // 后指定:

src := "https://github.com/hashicorp/go-getter.git//testdata"

校验和

可以为文件下载添加校验和验证:

src := "./foo.txt?checksum=md5:b7d96c89d09d9e204f5fedc4d5d55b21"

解压缩

go-getter 会自动根据文件扩展名解压缩文件:

src := "./foo.zip"  // 自动解压
src := "./some/path?archive=false"  // 禁用解压

协议特定选项

Git 选项

src := "github.com/hashicorp/go-getter?ref=abcd1234"  // 指定 Git 引用

HTTP 选项

// 基本认证
src := "https://Aladdin:OpenSesame@www.example.com/index.html"

// 自定义 HTTP 头
var httpGetter = &getter.HttpGetter{
    Header: make(map[string][]string),
}
httpGetter.Header.Add("X-Example", "value")

S3 选项

src := "s3::https://s3.amazonaws.com/bucket/foo?aws_access_key_id=KEY&aws_access_key_secret=SECRET"

安全选项

禁用符号链接

client := getter.Client{
    DisableSymlinks: true,
}

HTTP 超时设置

var httpGetter = &getter.HttpGetter{
    ReadTimeout: 30 * time.Second,
    MaxBytes: 500000000, // 500 MB
}

Git 超时设置

var gitGetter = &getter.GitGetter{
    Timeout: 5 * time.Minute,
}

完整示例

下面是一个完整的示例,展示了如何使用 go-getter 从 GitHub 下载特定分支的代码:

package main

import (
    "log"
    "github.com/hashicorp/go-getter"
)

func main() {
    // 定义下载源(GitHub 仓库的特定分支)
    src := "github.com/hashicorp/go-getter?ref=main"
    
    // 定义目标路径
    dst := "./downloaded-repo"
    
    // 创建客户端配置
    client := &getter.Client{
        Src:  src,
        Dst:  dst,
        Dir:  true,
        
        // 安全配置
        DisableSymlinks: true,
    }
    
    // 执行下载
    if err := client.Get(); err != nil {
        log.Fatalf("下载失败: %s", err)
    }
    
    log.Printf("成功下载到: %s", dst)
}

这个示例展示了如何从 GitHub 下载主分支的代码,并保存到本地目录,同时启用了安全选项。


更多关于golang通过URL从多种来源下载文件或目录的插件库go-getter的使用的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于golang通过URL从多种来源下载文件或目录的插件库go-getter的使用的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


使用go-getter库从多种来源下载文件或目录

go-getter是一个功能强大的Go库,用于从多种来源(HTTP、HTTPS、S3、Git等)下载文件或整个目录。它提供了统一的接口来处理不同类型的下载源,支持解压缩和校验等功能。

安装

go get github.com/hashicorp/go-getter

基本使用示例

1. 简单文件下载

package main

import (
	"github.com/hashicorp/go-getter"
	"log"
)

func main() {
	// 定义源URL和目标路径
	src := "https://example.com/file.zip"
	dst := "./local/file.zip"

	// 创建客户端
	client := &getter.Client{
		Src:  src,
		Dst:  dst,
		Mode: getter.ClientModeFile, // 下载单个文件
	}

	// 执行下载
	if err := client.Get(); err != nil {
		log.Fatalf("下载失败: %s", err)
	}
	log.Println("下载完成")
}

2. 下载并自动解压

func downloadAndExtract() {
	client := &getter.Client{
		Src:  "https://example.com/archive.zip",
		Dst:  "./extracted/",
		Mode: getter.ClientModeDir, // 下载并解压到目录
	}

	if err := client.Get(); err != nil {
		log.Fatalf("下载解压失败: %s", err)
	}
	log.Println("下载并解压完成")
}

3. 从Git仓库下载

func downloadFromGit() {
	client := &getter.Client{
		Src:  "git::https://github.com/user/repo.git",
		Dst:  "./repo/",
		Mode: getter.ClientModeDir,
	}

	if err := client.Get(); err != nil {
		log.Fatalf("Git克隆失败: %s", err)
	}
	log.Println("Git仓库克隆完成")
}

高级功能

1. 使用进度条

func downloadWithProgress() {
	pwd := "/tmp"
	client := &getter.Client{
		Src:  "https://example.com/largefile.bin",
		Dst:  "./largefile.bin",
		Pwd:  pwd,
		Mode: getter.ClientModeFile,
		// 进度回调
		Getters: map[string]getter.Getter{
			"http": &getter.HttpGetter{
				Netrc: true,
				ProgressListener: &getter.ProgressTracker{
					Callback: func(current, total int64) {
						percent := float64(current) / float64(total) * 100
						log.Printf("下载进度: %.2f%%", percent)
					},
				},
			},
		},
	}

	if err := client.Get(); err != nil {
		log.Fatalf("下载失败: %s", err)
	}
}

2. 下载到临时目录

func downloadToTemp() {
	tmpDir, err := os.MkdirTemp("", "download")
	if err != nil {
		log.Fatalf("创建临时目录失败: %s", err)
	}
	defer os.RemoveAll(tmpDir)

	client := &getter.Client{
		Src:  "https://example.com/tempfile.zip",
		Dst:  tmpDir,
		Mode: getter.ClientModeDir,
	}

	if err := client.Get(); err != nil {
		log.Fatalf("下载失败: %s", err)
	}
	log.Printf("文件下载到临时目录: %s", tmpDir)
}

3. 使用校验和验证

func downloadWithChecksum() {
	client := &getter.Client{
		Src:     "https://example.com/important.zip",
		Dst:     "./important.zip",
		Mode:    getter.ClientModeFile,
		Options: []getter.ClientOption{
			getter.WithChecksum("md5:b10a8db164e0754105b7a99be72e3fe5"),
		},
	}

	if err := client.Get(); err != nil {
		log.Fatalf("下载或校验失败: %s", err)
	}
	log.Println("文件下载并校验成功")
}

支持的协议和源

go-getter支持多种协议和源:

  • HTTP/HTTPS
  • S3
  • Git (git::https://..., git::ssh://...)
  • Mercurial (hg::...)
  • 本地文件 (file://...)
  • 压缩文件 (自动解压.zip, .tar.gz等)

最佳实践

  1. 错误处理:总是检查Get()返回的错误
  2. 清理资源:下载到临时目录时记得清理
  3. 进度反馈:大文件下载时使用进度回调
  4. 校验:重要文件使用校验和验证
  5. 并发控制:大量下载时考虑限制并发数

go-getter是一个功能全面且灵活的库,可以大大简化从各种来源下载文件的复杂性。通过统一的API,开发者可以轻松处理不同类型的下载需求。

回到顶部