Skip to content

go 分批读取http应答数据

Published: at 09:38 AM | 2 min read

我们读取http应答通常用:

ioutil.ReadAll(resp.Body)

很好用也很方便,但是如果应答的包很大时(下载文件),不仅会分配很大的内存而且慢。 所以我们需要分批读取,每次读取一块直到所有应答读取完成。

代码如下:

func ReadChunk(r io.Reader, maxChunkSize int, chanChunk chan<- []byte) {
	for {
		buf := make([]byte, maxChunkSize)
		n, err := r.Read(buf)
		if n < 0 {
			break
		}
		if err != nil && err != io.EOF {
			break
		}
		chanChunk <- buf[:n]
		if err == io.EOF {
			break
		}
	}
	close(chanChunk)
}

如下,可以这样处理数据:

	chanChunk := make(chan []byte, 5)
	go ReadChunk(resp.Body, maxUploadSize/2, chanChunk)
	total := 0
	for chunk := range chanChunk {
		total += len(chunk)
		goutil.PanicIfErr(goutil.WriteFileAppend(to, chunk))
		fmt.Printf("\r%d %s\t", total, goutil.FormatBytes(float64(total)))
	}