dl

package module
v1.0.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2026 License: MIT Imports: 12 Imported by: 0

README

dl

Go Reference Go Report Card

一个高性能的 Go 语言文件下载器库,支持多协程并发下载、断点续传和实时进度跟踪。

✨ 特性

  • 🚀 高性能并发下载 - 支持多协程并发下载,充分利用带宽
  • 📦 断点续传 - 下载中断后可从上次位置继续
  • 📊 实时进度 - 精确显示下载进度和速率(保留两位小数)
  • 🎯 灵活配置 - 通过函数式选项轻松配置下载行为
  • 🌐 代理支持 - 支持 HTTP、HTTPS、SOCKS5 代理和系统代理
  • 🛡️ 线程安全 - 使用原子操作和互斥锁保证并发安全
  • 🎮 控制操作 - 支持开始、暂停、恢复、停止等操作
  • 📝 事件回调 - 提供下载开始、进度更新、完成和取消等回调

📦 安装

go get -u github.com/wsshow/dl

🚀 快速开始

基础用法
package main

import (
	"fmt"
	"github.com/wsshow/dl"
)

func main() {
	url := "https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz"
	
	// 创建下载器
	downloader := dl.NewDownloader(url)
	
	// 设置进度回调
	downloader.OnProgress(func(loaded, total int64, rate string) {
		progress := float64(loaded) / float64(total) * 100
		fmt.Printf("\r下载进度: %.2f%%, 速度: %s", progress, rate)
	})
	
	// 开始下载
	if err := downloader.Start(); err != nil {
		fmt.Printf("下载失败: %v\n", err)
		return
	}
	
	fmt.Println("\n下载完成!")
}
高级用法
package main

import (
	"fmt"
	"github.com/wsshow/dl"
)

func main() {
	url := "https://example.com/large-file.zip"
	
	// 使用配置选项创建下载器
	downloader := dl.NewDownloader(url,
		dl.WithFileName("my-download.zip"),    // 自定义文件名
		dl.WithConcurrency(8),                  // 8个并发协程
		dl.WithBaseDir("./downloads/cache"),    // 自定义缓存目录
		dl.WithResume(true),                    // 启用断点续传
		dl.WithProxy("http://127.0.0.1:7890"), // 使用HTTP代理
	)
	
	// 设置下载开始回调
	downloader.OnDownloadStart(func(total int64, filename string) {
		fmt.Printf("开始下载: %s (大小: %d 字节)\n", filename, total)
	})
	
	// 设置进度回调
	downloader.OnProgress(func(loaded, total int64, rate string) {
		progress := float64(loaded) / float64(total) * 100
		fmt.Printf("\r进度: %.2f%% | 速度: %s | %d/%d 字节", 
			progress, rate, loaded, total)
	})
	
	// 设置完成回调
	downloader.OnDownloadFinished(func(filename string) {
		fmt.Printf("\n✅ 下载完成: %s\n", filename)
	})
	
	// 设置取消回调
	downloader.OnDownloadCanceled(func(filename string) {
		fmt.Printf("\n❌ 下载取消: %s\n", filename)
	})
	
	// 开始下载
	if err := downloader.Start(); err != nil {
		fmt.Printf("下载错误: %v\n", err)
	}
}
交互式控制
package main

import (
	"fmt"
	"github.com/wsshow/dl"
)

func main() {
	url := "https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz"
	
	downloader := dl.NewDownloader(url)
	
	downloader.OnProgress(func(loaded, total int64, rate string) {
		progress := float64(loaded) / float64(total) * 100
		fmt.Printf("\r进度: %.2f%%, 速度: %s", progress, rate)
	})
	
	downloader.OnDownloadStart(func(total int64, filename string) {
		fmt.Printf("开始下载文件: %s (大小: %d 字节)\n", filename, total)
	})
	
	downloader.OnDownloadFinished(func(filename string) {
		fmt.Printf("\n%s: 下载完成\n", filename)
	})
	
	downloader.OnDownloadCanceled(func(filename string) {
		fmt.Printf("\n%s: 下载已取消\n", filename)
	})
	
	var command string
	for {
		fmt.Println("\n命令:")
		fmt.Println("  q - 退出")
		fmt.Println("  b - 开始下载")
		fmt.Println("  s - 停止下载")
		fmt.Println("  p - 暂停下载")
		fmt.Println("  r - 恢复下载")
		fmt.Print("\n请输入命令: ")
		
		_, err := fmt.Scanln(&command)
		if err != nil {
			fmt.Println("输入错误,请重试")
			continue
		}
		
		switch command {
		case "q":
			fmt.Println("退出程序")
			return
		case "b":
			go func() {
				if err := downloader.Start(); err != nil {
					fmt.Printf("启动错误: %v\n", err)
				}
			}()
		case "s":
			if err := downloader.Stop(); err != nil {
				fmt.Printf("停止错误: %v\n", err)
			} else {
				return
			}
		case "p":
			if err := downloader.Pause(); err != nil {
				fmt.Printf("暂停错误: %v\n", err)
			}
		case "r":
			go func() {
				if err := downloader.Resume(); err != nil {
					fmt.Printf("恢复错误: %v\n", err)
				}
			}()
		default:
			fmt.Println("未知命令")
		}
	}
}
代理配置
package main

import (
	"fmt"
	"github.com/wsshow/dl"
)

func main() {
	url := "https://example.com/file.zip"
	
	// 示例1: 使用 HTTP 代理
	downloader1 := dl.NewDownloader(url,
		dl.WithProxy("http://127.0.0.1:7890"),
		dl.WithFileName("file1.zip"),
	)
	
	// 示例2: 使用 SOCKS5 代理
	downloader2 := dl.NewDownloader(url,
		dl.WithProxy("socks5://127.0.0.1:1080"),
		dl.WithFileName("file2.zip"),
	)
	
	// 示例3: 使用系统代理(自动读取环境变量)
	downloader3 := dl.NewDownloader(url,
		dl.WithSystemProxy(),
		dl.WithFileName("file3.zip"),
	)
	
	// 示例4: 使用带认证的代理
	downloader4 := dl.NewDownloader(url,
		dl.WithProxy("http://username:password@proxy.example.com:8080"),
		dl.WithFileName("file4.zip"),
	)
	
	// 示例5: 自定义 HTTP 客户端(高级用法)
	customClient := &http.Client{
		Timeout: 30 * time.Second,
		Transport: &http.Transport{
			MaxIdleConns:        100,
			MaxIdleConnsPerHost: 10,
			IdleConnTimeout:     90 * time.Second,
		},
	}
	downloader5 := dl.NewDownloader(url,
		dl.WithHTTPClient(customClient),
		dl.WithFileName("file5.zip"),
	)
	
	// 开始下载
	if err := downloader1.Start(); err != nil {
		fmt.Printf("下载失败: %v\n", err)
	}
}

代理配置说明:

  • HTTP/HTTPS 代理: WithProxy("http://proxy.com:8080")
  • SOCKS5 代理: WithProxy("socks5://127.0.0.1:1080")
  • 系统代理: WithSystemProxy() - 自动读取 HTTP_PROXYHTTPS_PROXYNO_PROXY 环境变量
  • 代理认证: 在 URL 中包含用户名和密码,如 http://user:pass@proxy.com:8080

📖 API 文档

创建下载器
func NewDownloader(url string, opts ...OptionFunc) *Downloader

创建一个新的下载器实例。

参数:

  • url - 要下载的文件URL地址
  • opts - 可选的配置函数

返回:

  • *Downloader - 下载器实例
配置选项
// 设置下载文件名
func WithFileName(filename string) OptionFunc

// 设置缓存目录
func WithBaseDir(basedir string) OptionFunc

// 设置并发协程数(0表示使用CPU核心数)
func WithConcurrency(concurrency int) OptionFunc

// 设置是否启用断点续传
func WithResume(resume bool) OptionFunc

// 设置自定义HTTP客户端
func WithHTTPClient(client *http.Client) OptionFunc

// 设置代理服务器(支持 HTTP、HTTPS、SOCKS5)
func WithProxy(proxyURL string) OptionFunc

// 使用系统代理设置(读取环境变量)
func WithSystemProxy() OptionFunc
控制方法
// 开始下载
func (d *Downloader) Start() error

// 停止下载
func (d *Downloader) Stop() error

// 暂停下载(Stop的别名)
func (d *Downloader) Pause() error

// 恢复下载(Start的别名)
func (d *Downloader) Resume() error
事件回调
// 设置进度回调(频繁调用,避免耗时操作)
func (d *Downloader) OnProgress(f func(loaded int64, total int64, rate string))

// 设置下载开始回调
func (d *Downloader) OnDownloadStart(f func(total int64, filename string))

// 设置下载完成回调
func (d *Downloader) OnDownloadFinished(f func(filename string))

// 设置下载取消回调
func (d *Downloader) OnDownloadCanceled(f func(filename string))

🔧 配置说明

Options 结构
type Options struct {
    FileName    string       // 下载后保存的文件名(包含路径)
    BaseDir     string       // 多协程下载时分片文件的缓存目录
    Concurrency int          // 并发下载的协程数,0表示使用CPU核心数
    Resume      bool         // 是否启用断点续传功能
    HTTPClient  *http.Client // 自定义HTTP客户端,可用于配置代理、超时等
}
默认配置
  • 并发数: 等于CPU核心数
  • 缓存目录: downloader_cache
  • 文件名: 从URL中提取
  • 断点续传: 启用

🎯 性能优化

  1. 并发控制: 根据网络带宽调整并发数,通常CPU核心数是较好的起点
  2. 缓冲区大小: 默认32KB缓冲区,适合大多数场景
  3. 断点续传: 对于大文件或不稳定网络环境建议启用
  4. 原子操作: 使用atomic包减少锁竞争,提高并发性能

🔒 线程安全

该库在设计时充分考虑了并发安全:

  • 使用sync.Mutex保护共享状态
  • 使用atomic包进行原子操作
  • 使用sync.Map管理取消函数
  • 所有公共方法都是线程安全的

📝 注意事项

  1. Progress回调: 该回调会被频繁调用,避免在其中执行耗时操作
  2. 文件权限: 确保程序对目标目录有写入权限
  3. 磁盘空间: 下载前确保有足够的磁盘空间(至少是文件大小的2倍)
  4. 并发限制: 过高的并发数可能导致服务器限流或连接失败
  5. URL有效性: 确保提供的URL可访问且支持HTTP/HTTPS协议

🤝 贡献

欢迎提交Issue和Pull Request!

📄 许可证

本项目采用 MIT 许可证。详见 LICENSE 文件。

Documentation

Index

Constants

View Source
const (
	// DefaultConcurrency 默认并发下载数
	DefaultConcurrency = 0 // 0表示使用runtime.NumCPU()
	// DefaultBaseDir 默认缓存目录
	DefaultBaseDir = "downloader_cache"
	// DefaultBufferSize 默认缓冲区大小
	DefaultBufferSize = 32 * 1024
	// RateUpdateInterval 速率更新间隔
	RateUpdateInterval = 250 * time.Millisecond
	// FilePerm 文件权限
	FilePerm = 0644
	// DirPerm 目录权限
	DirPerm = 0755
)

常量定义

Variables

View Source
var (
	// ErrAlreadyStopped 下载器已停止错误
	ErrAlreadyStopped = errors.New("downloader has been stopped")
	// ErrInvalidURL URL无效错误
	ErrInvalidURL = errors.New("invalid download URL")
	// ErrInvalidConcurrency 并发数无效错误
	ErrInvalidConcurrency = errors.New("concurrency must be greater than 0")
)

错误定义

Functions

This section is empty.

Types

type Downloader

type Downloader struct {
	// contains filtered or unexported fields
}

Downloader 文件下载器,支持多协程并发下载和断点续传

func NewDownloader

func NewDownloader(url string, opts ...OptionFunc) *Downloader

NewDownloader 创建一个新的文件下载器实例

参数:

url - 要下载的文件URL地址
opts - 可选的配置函数,用于自定义下载行为

返回:

*Downloader - 配置好的下载器实例

示例:

dl := NewDownloader("https://example.com/file.zip",
    WithConcurrency(8),
    WithResume(true))

func (*Downloader) OnDownloadCanceled

func (d *Downloader) OnDownloadCanceled(f func(filename string))

OnDownloadCanceled 设置下载被取消时的回调函数

参数:

f - 回调函数,接收被取消的文件名

func (*Downloader) OnDownloadFinished

func (d *Downloader) OnDownloadFinished(f func(filename string))

OnDownloadFinished 设置下载成功完成后的回调函数

参数:

f - 回调函数,接收已完成的文件名

func (*Downloader) OnDownloadStart

func (d *Downloader) OnDownloadStart(f func(total int64, filename string))

OnDownloadStart 设置下载开始时的回调函数

参数:

f - 回调函数,接收文件总大小和文件名

func (*Downloader) OnProgress

func (d *Downloader) OnProgress(f func(loaded int64, total int64, rate string))

OnProgress 设置下载进度回调函数

参数:

f - 回调函数,接收已下载字节数、总字节数和当前速率

注意: 此回调会被频繁调用,应避免执行耗时操作

func (*Downloader) Pause

func (d *Downloader) Pause() error

Pause 暂停下载(Stop的别名)

此方法与Stop()行为完全相同。如果启用了断点续传, 可以通过调用Resume()从上次停止的位置继续下载。

返回:

error - 如果下载器已经停止则返回ErrAlreadyStopped,否则返回nil

func (*Downloader) Resume

func (d *Downloader) Resume() error

Resume 恢复之前暂停的下载(Start的别名)

如果启用了断点续传,将从上次停止的位置继续下载。

返回:

error - 下载过程中的错误,成功则返回nil

func (*Downloader) Start

func (d *Downloader) Start() error

Start 开始执行下载任务

如果下载器之前被停止,会自动重新初始化

返回:

error - 下载过程中的错误,成功则返回nil

func (*Downloader) Stop

func (d *Downloader) Stop() error

Stop 停止正在进行的下载任务

此方法会取消所有正在进行的下载协程,但不会删除已下载的分片文件。 如果启用了断点续传,可以通过调用Resume()继续下载。

返回:

error - 如果下载器已经停止则返回ErrAlreadyStopped,否则返回nil

type OptionFunc

type OptionFunc func(*Options)

OptionFunc 配置函数

func WithBaseDir

func WithBaseDir(basedir string) OptionFunc

WithBaseDir 设置多协程下载时文件的缓存目录

func WithConcurrency

func WithConcurrency(concurrency int) OptionFunc

WithConcurrency 设置并发下载数

func WithFileName

func WithFileName(path string) OptionFunc

WithFileName 设置下载的文件名或路径 如果 path 包含路径分隔符,将同时设置 FilePath 和 FileName

func WithHTTPClient added in v1.0.4

func WithHTTPClient(client *http.Client) OptionFunc

WithHTTPClient 设置自定义的HTTP客户端 可用于配置超时、重试策略、TLS配置等

func WithProxy added in v1.0.4

func WithProxy(proxyURL string) OptionFunc

WithProxy 设置代理服务器 proxyURL 代理服务器地址,例如:"http://127.0.0.1:7890" 或 "socks5://127.0.0.1:1080"

func WithResume

func WithResume(resume bool) OptionFunc

WithResume 设置是否启用下载缓存

func WithSystemProxy added in v1.0.4

func WithSystemProxy() OptionFunc

WithSystemProxy 使用系统代理设置 会自动读取系统的 HTTP_PROXY、HTTPS_PROXY 和 NO_PROXY 环境变量

type Options

type Options struct {
	// FileName 指定下载后保存的文件名(不包含路径)
	FileName string
	// FilePath 指定下载后保存的完整路径(包含目录和文件名)
	FilePath string
	// BaseDir 多协程下载时分片文件的缓存目录
	BaseDir string
	// Concurrency 并发下载的协程数,0表示使用CPU核心数
	Concurrency int
	// Resume 是否启用断点续传功能
	Resume bool
	// HTTPClient 自定义HTTP客户端,可用于配置代理、超时等
	HTTPClient *http.Client
}

Options 下载器配置选项

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL