Documentation
¶
Overview ¶
Package grab provides a HTTP download manager implementation.
Get is the most simple way to download a file:
resp, err := grab.Get("/tmp", "http://example.com/example.zip") // ...
Get will download the given URL and save it to the given destination directory. The destination filename will be determined automatically by grab using Content-Disposition headers returned by the remote server, or by inspecting the requested URL path.
An empty destination string or "." means the transfer will be stored in the current working directory.
If a destination file already exists, grab will assume it is a complete or partially complete download of the requested file. If the remote server supports resuming interrupted downloads, grab will resume downloading from the end of the partial file. If the server does not support resumed downloads, the file will be retransferred in its entirety. If the file is already complete, grab will return successfully.
For control over the HTTP client, destination path, auto-resume, checksum validation and other settings, create a Client:
client := grab.NewClient() client.HTTPClient.Transport.DisableCompression = true req, err := grab.NewRequest("/tmp", "http://example.com/example.zip") // ... req.NoResume = true req.HTTPRequest.Header.Set("Authorization", "Basic YWxhZGRpbjpvcGVuc2VzYW1l") resp := client.Do(req) // ...
You can monitor the progress of downloads while they are transferring:
client := grab.NewClient() req, err := grab.NewRequest("", "http://example.com/example.zip") // ... resp := client.Do(req) t := time.NewTicker(time.Second) defer t.Stop() for { select { case <-t.C: fmt.Printf("%.02f%% complete\n", resp.Progress()) case <-resp.Done: if err := resp.Err(); err != nil { // ... } // ... return } }
Index ¶
- Variables
- func X多线程下载(线程数 int, 保存目录 string, 下载链接 ...string) (<-chan *Response, error)
- func X是否为状态码错误(错误 error) bool
- type Client
- type HTTPClient
- type Hook
- type RateLimiter
- type Request
- type Response
- func (c *Response) X取下载已持续时间() time.Duration
- func (c *Response) X取估计完成时间() time.Time
- func (c *Response) X取总字节() int64
- func (c *Response) X取每秒字节() float64
- func (c *Response) X取消() error
- func (c *Response) X取进度() float64
- func (c *Response) X已完成字节() int64
- func (c *Response) X是否已完成() bool
- func (c *Response) X等待完成()
- func (c *Response) X等待完成后取字节集() ([]byte, error)
- func (c *Response) X等待完成后打开文件() (io.ReadCloser, error)
- func (c *Response) X等待错误() error
- type StatusCodeError
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ( // ErrBadLength表示服务器响应或现有文件的长度与预期内容长度不符。 // md5:da55fb8042067108 ERR_文件长度不匹配 = errors.New("bad content length") // ErrBadChecksum 表示下载的文件未能通过校验和验证。 // md5:ac12cf077b834024 ERR_文件校验失败 = errors.New("checksum mismatch") // ErrNoFilename表示无法使用服务器的URL或响应头自动确定一个合理的文件名。 // md5:9a298d198ab7a9e5 ERR_无法确定文件名 = errors.New("no filename could be determined") // ErrNoTimestamp表示无法使用远程服务器响应头自动确定时间戳。 // md5:b68398288f9bf056 ERR_无法确定时间戳 = errors.New("no timestamp could be determined for the remote file") // ErrFileExists 表示目标路径已经存在。 md5:aa4e242a296ca268 ERR_文件已存在 = errors.New("file exists") )
var DefaultClient = X创建客户端()
DefaultClient 是默认客户端,所有 Get 方便函数都会使用它。 md5:3aee22c6e017f0f3
Functions ¶
Types ¶
type Client ¶
type Client struct { // HTTPClient 指定了在文件传输过程中与远程服务器通信所使用的 http.Client。 // md5:18f90ae2438c3d95 HTTPClient HTTPClient // UserAgent 指定将设置为此客户端的所有请求的头中的 User-Agent 字符串。 // // 可以在每个请求的头中覆盖 User-Agent 字符串。 // md5:416ff171bdbaf067 HTTP_UA string // BufferSize 指定了用于传输所有请求文件的缓冲区的大小(以字节为单位)。较大的缓冲区可能会提高吞吐量,但会消耗更多内存,并导致传输进度统计更新更不频繁。每个请求的BufferSize可以在每个Request对象上重写。默认值:32KB。 // md5:76d8523deca24178 X缓冲区大小 int }
Client是一个文件下载客户端。
客户端是安全的,可以由多个goroutine并发使用。 md5:adb110330920265b
func (*Client) DoChannel ¶
DoChannel 通过给定的 Request 通道顺序执行所有发送的请求,直到由其他goroutine关闭。调用者会在Request通道关闭且所有传输完成后被阻塞。一旦从远程服务器接收到响应,所有响应会立即通过给定的Response通道发送,并可用于跟踪每个下载的进度。
如果Response接收器处理速度慢,会导致worker阻塞,从而延迟已经启动连接的传输开始时间——可能导致服务器超时。调用者需要确保为Response通道使用足够的缓冲大小以防止这种情况。
在任何文件传输过程中如果发生错误,可以通过关联的Response.Err函数访问到该错误。 md5:1e8b3d5e8dee8a95
Example ¶
此示例使用DoChannel创建一个生产者/消费者模型,用于并发下载多个文件。 这与DoBatch在内部使用DoChannel的工作方式类似,不同之处在于它允许调用者持续发送新请求, 直到他们希望关闭请求通道为止。 md5:8cfd63343a82362c
// 创建一个请求和一个缓冲的响应通道 md5:c4b7d02b204abf79 reqch := make(chan *Request) respch := make(chan *Response, 10) // start 4 workers client := X创建客户端() wg := sync.WaitGroup{} for i := 0; i < 4; i++ { wg.Add(1) go func() { client.DoChannel(reqch, respch) wg.Done() }() } go func() { // send requests for i := 0; i < 10; i++ { url := fmt.Sprintf("http://example.com/example%d.zip", i+1) req, err := X生成下载参数("/tmp", url) if err != nil { panic(err) } reqch <- req } close(reqch) // 等待工人完成 md5:b758a6709f2c0bc0 wg.Wait() close(respch) }() // check each response for resp := range respch { // block until complete if err := resp.X等待错误(); err != nil { panic(err) } fmt.Printf("Downloaded %s to %s\n", resp.X下载参数.X取下载链接(), resp.X文件名) }
Output:
type HTTPClient ¶
HTTPClient 提供了一个接口,允许我们执行HTTP请求。 md5:4171bffd13d00b3a
type Hook ¶
Hook 是用户提供的回调函数,可以在请求生命周期的各个阶段由 grab 调用。 如果钩子函数返回错误,关联的请求将被取消,并且相同的错误将返回在 Response 对象上。
钩子函数是同步调用的,应避免不必要的阻塞。 诸如 Response.Err、Response.Cancel 或 Response.Wait 这些会阻塞直到下载完成的 Response 方法会导致死锁。 若要从回调函数中取消下载,只需返回一个非空错误。 md5:b4013e6bf57cee77
type RateLimiter ¶
RateLimiter 是一个接口,任何第三方的速率限制器都必须实现这个接口,以限制下载传输速度。
推荐的令牌桶实现可以在 https://godoc.org/golang.org/x/time/rate#Limiter 找到。 md5:cd1978873813ac86
Example ¶
req, _ := X生成下载参数("", "http://www.golang-book.com/public/pdf/gobook.pdf") // 附加一个1Mbps速率限制器,类似于golang.org/x/time/rate包中的令牌桶实现。 // md5:a33151d1a418a247 req.X速率限制器 = NewLimiter(1048576) resp := DefaultClient.X下载(req) if err := resp.X等待错误(); err != nil { log.Fatal(err) }
Output:
type Request ¶
type Request struct { // Label是一个任意字符串,可以用来将Request标记为一个用户友好的名称。 // md5:48c76f58a675938f X名称 string // Tag 是一个任意的接口,可以用来将请求与其他数据相关联。 // md5:cca083a2da336d7a Tag interface{} // HTTPRequest 指定了要发送到远程服务器以启动文件传输的HTTP请求。它包括URL、协议版本、HTTP方法、请求头和身份验证等请求配置信息。 // md5:8b29a36ebccc4fbf Http协议头 *http.Request // Filename 指定了文件传输将在本地存储的位置。如果 Filename 为空或是一个目录,将使用 Content-Disposition 头部或请求 URL 来解析实际的文件名。 // // 空字符串表示文件传输将存储在当前工作目录下。 // md5:b2487dc28865af4e X文件名 string // SkipExisting 指定如果目标路径已经存在,应该返回 ErrFileExists 错误。不会检查已存在的文件是否完整。 // md5:fcfcc6296df94857 X跳过已存在文件 bool // NoResume 指定在不尝试恢复任何现有文件的情况下,部分下载将被重新启动。如果下载已经完整完成,它将不会被重新启动。 // md5:5d7097b2011a8aed X不续传 bool // NoStore 指定 grab 不应将内容写入本地文件系统。相反,下载的内容将存储在内存中,仅可通过 Response.Open 或 Response.Bytes 访问。 // md5:b250d7f0915c2e35 X不写入本地文件系统 bool // NoCreateDirectories 指定在给定的Filename路径中,任何缺失的目录不应该自动创建,如果它们尚不存在的话。 // md5:f9491a6bdafa1a03 X不自动创建目录 bool // IgnoreBadStatusCodes 指定grab应该接受远程服务器返回的任何状态码。否则,grab期望响应状态码在200(跟随重定向后)范围内。 // md5:0cfc61395f3c8fda X忽略错误状态码 bool // IgnoreRemoteTime 指定 grab 不应尝试将本地文件的时间戳设置为与远程文件匹配。 // md5:4b121c28c096e635 X忽略远程时间 bool // Size 指定如果已知的话,文件传输的预期大小。如果服务器响应的大小与预期不符, // 传输将被取消并返回 ErrBadLength 错误。 // md5:4d6feeb012ab2e19 X预期文件大小 int64 // BufferSize 指定了用于传输请求文件的缓冲区的字节数。更大的缓冲区可能会提高吞吐量,但会消耗更多内存,并减少传输进度统计信息的更新频率。如果配置了速率限制器,BufferSize 应远低于速率限制。默认值:32KB。 // md5:c943b23cdf634593 X缓冲区大小 int // RateLimiter 用于限制下载的传输速率。给定的 Request.BufferSize 决定了RateLimiter将多久被查询一次。 // md5:86949911252236b7 X速率限制器 RateLimiter // BeforeCopy 是用户提供的回调函数,它在请求开始下载之前立即被调用。如果 BeforeCopy 返回错误,请求将被取消,并且相同的错误将返回在响应对象中。 // md5:865a949d97572fb2 X传输开始之前回调 Hook // AfterCopy 是用户提供的回调,它在请求下载完成后立即调用,但在校验和验证和关闭之前。此钩子仅在传输成功时调用。如果 AfterCopy 返回错误,请求将被取消,并在 Response 对象上返回相同的错误。 // md5:9e8a840d6dbbf503 X传输完成之后回调 Hook // contains filtered or unexported fields }
Request表示客户端要发送的HTTP文件传输请求。 md5:3bbb6f4b848425e8
func (*Request) I取上下文 ¶
Context 返回请求的上下文。要更改上下文,请使用 WithContext。
返回的上下文始终非空;它默认为背景上下文。
上下文控制取消操作。 md5:48c4bb357919bed1
func (*Request) WithContext ¶
WithContext 返回一个与 r 拥有相同结构但上下文改为 ctx 的浅拷贝。提供的 ctx 必须非 nil。 md5:717222e0b2288cb8
Example ¶
// 使用100毫秒超时创建上下文 md5:20d987ef3ab9f9e9 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() // 使用上下文创建下载请求 md5:cd71b43cad23f3e2 req, err := X生成下载参数("", "http://example.com/example.zip") if err != nil { panic(err) } req = req.WithContext(ctx) // send download request resp := DefaultClient.X下载(req) if err := resp.X等待错误(); err != nil { fmt.Println("error: request cancelled") }
Output: error: request cancelled
type Response ¶
type Response struct { // 提交以获取此响应的请求。 md5:75fc5e8790cf3c19 X下载参数 *Request // HTTPResponse 表示从 HTTP 请求接收到的 HTTP 响应。 // // 响应体不应该被使用,因为它会被 grab 消费并关闭。 // md5:de050e04bc066b54 HTTP响应 *http.Response // Filename 指定了文件传输在本地存储中的路径。 // md5:2739dccaf6d8bae1 X文件名 string // Start 指定文件传输开始的时间。 md5:0b7ef91daaa881e6 X传输开始时间 time.Time // End 指定文件传输完成的时间。 // // 在传输完成之前,此函数将返回零值。 // md5:22aad30fb1342e5f X传输完成时间 time.Time // CanResume 指定远程服务器已宣布它可以恢复以前的下载,因为已设置 "Accept-Ranges: bytes" 头。 // md5:d5b949adac4b5a26 CanResume bool // DidResume 指定文件传输恢复了先前未完成的传输。 // md5:9e59c01300744b13 DidResume bool // Done 在传输完成时关闭,无论是成功还是出现错误。可以通过 Response.Err 获取错误信息。 // md5:a87b182e4efaa89f Done chan struct{} // contains filtered or unexported fields }
Response 表示已完成或正在进行的下载请求的响应。
一旦从远程服务器接收到HTTP响应,就可能返回一个响应,但在开始传输主体内容之前。
对Response方法的所有调用都是线程安全的。 md5:ddbfa271b1d4fd24
func X下载 ¶
Get 发送一个HTTP请求,并将请求的URL内容下载到给定的目标文件路径。调用者会在下载完成,无论成功还是失败时被阻塞。
如果由于客户端策略(如CheckRedirect)导致错误,或者出现HTTP协议或IO错误,会返回一个错误。
若要进行非阻塞调用,或者控制HTTP客户端头、重定向策略和其他设置,请创建一个Client。 md5:1bbde4e6e89ceb15
func (*Response) X取下载已持续时间 ¶
Duration 返回文件传输的持续时间。如果传输正在进行中,持续时间将是当前时间和传输开始时间之间的差。如果传输已完成,持续时间将是完成传输过程的开始和结束时间之间的差。 md5:851e9a4335644cc7
func (*Response) X取估计完成时间 ¶
ETA 返回给定当前每秒字节数(BytesPerSecond)下载预计完成的时间。如果传输已经完成,将返回实际结束时间。 md5:7f8fcb12ee64da7f
func (*Response) X取每秒字节 ¶
BytesPerSecond 返回过去五秒内的平均每秒传输字节数。如果下载已完成,则返回整个下载过程中的平均字节数/秒。 md5:dd425949dfaaf72f
func (*Response) X取消 ¶
Cancel 通过取消此 Response 的底层上下文来取消文件传输。Cancel 函数会阻塞直到传输关闭,并返回任何错误——通常为 context.Canceled。 md5:4277ad03dbb17f34
func (*Response) X等待完成后取字节集 ¶
Bytes 使调用的goroutine阻塞,直到底层文件传输完成,然后读取已完成传输的所有字节。如果启用了Request.NoStore,将从内存中读取字节。
如果在传输过程中发生错误,将返回该错误。 md5:af539342438b13c1
func (*Response) X等待完成后打开文件 ¶
func (c *Response) X等待完成后打开文件() (io.ReadCloser, error)
Open函数会让调用的goroutine阻塞,直到底层文件传输完成,然后打开已传输的文件以供阅读。如果Request.NoStore选项被启用,读取器将从内存中读取。
如果在传输过程中发生错误,该错误将被返回。
调用者有责任关闭返回的文件句柄。 md5:92d1addd1c15e703
type StatusCodeError ¶
type StatusCodeError int
StatusCodeError表示服务器响应的状态码不在200-299范围内(在跟踪任何重定向后)。 md5:d0a3bd375863dac3
func (StatusCodeError) Error ¶
func (err StatusCodeError) Error() string