Golang实现io.Reader的重复读取

该博客介绍了如何处理不支持Seek接口的io.Reader以实现重复读取。通过创建一个MultiReadable结构体,当reader不支持Seek时,将读取的内容缓存到bytes.Buffer中。在需要重读时,先从缓冲读取,缓冲读完再从原始reader读取。示例代码展示了如何从HTTP响应体中读取数据并重复读取,每次读取不同长度的数据片段。

io.Reader 如果是实现了io.Seeker接口,想要重复读取则比较简单,直接调用Seek()方法把offset移到起始处即可,比如本地文件的IO,如果不支持Seek想要重复读取,则相对麻烦,这里我们可以借助一个buffer,从io.Reader读取数据的时候,同时把读出来的数据写到这个buffer中缓存起来,当要重新读取时,先从buffer里读,buffer读完再接着从原始的io.Reader里读,代码如下:

import (
	"bytes"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net/http"
	"time"
)

type MultiReadable struct {
   
   
	originReader io.Reader
	reader       io.Reader
	cache        *bytes.Buffer
}

func NewMultiReadable(reader io.Reader) *MultiReadable {
   
   
	return &MultiReadable{
   
   
		originReader: reader,
		reader:       reader,
	}
}

func (mr *MultiReadable) Read(p []byte) (int, error) {
   
   
	n, err := mr.reader.Read(p)
	// 如果 reader 不支持Seek,则把读取出来的内容同时写入到一个buffer中
	if _, ok := mr.reader.(io.Seeker); !ok && n > 0 {
   
   
		if mr.cache == nil {
   
   
			mr.cache = &bytes
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值