Go语言网络爬虫多重读取器的实现
相比前面两节中介绍的缓冲器和缓冲池,多重读取器的实现就简单多了。首先是基本结构:
实际上,当碰到 io.EOF 错误时,该函数就会返回读到的所有数据,这正是 data 字段所代表的数据。另外,*myMultipleReader 应该作为 MultipleReader 接口的实现类型。对于后者声明的唯一方法,其实现极其简单:
*bytes.Reader 类型是 io.Reader 接口的一个实现类型,不过我们这里需要的是 io.ReadCloser 接口类型的值。所以,需要使用 ioutil.NopCloser 函数对这个 *bytes.Reader 类型的值进行简单的包装。ioutil.NopCloser 函数会返回一个 io.ReadCloser 类型的值。
之前说过,io.ReadCloser 接口只比 io.Reader 多声明了一个 Close 方法,这个 Close 方法没有参数声明,但有一个 error 类型的结果声明。然而,ioutil.NopCloser 函数的结果值的 Close 方法永远只会返回 nil。也正因为如此,我们常常用这个函数包装无需关闭的读取器,这就是 NopCloser 的含义。
多重读取器的 Reader 方法总是返回一个新的可关闭读取器。因此,我可以利用它多次读取底层数据,并可以用该方法的结果值替代原先的 HTTP 响应的 Body 字段值很多次,这也是“多重”的真正含义。
//多重读取器的实现类型 type myMultipleReader struct { data []byte }非常简单和直接,多重读取器只保存要读取的实际数据。NewMultipleReader 用于新建一个多重读取器的实例:
//用于新建并返回一个多重读取器的实例 func NewMultipleReader(reader io.Reader) (MultipleReader, error) { var data []byte var err error if reader != nil { data, err = ioutil.ReadAll(reader) if err != nil { return nil, fmt.Errorf("multipie reader: couldn't create a new one: %s", err) } } else { data = []byte{} } return &myMultipleReader{ data: data, }, nil }标准库代码包 ioutil 中有一些非常实用的函数。这里用到的 ReadAll 函数的功能是,通过作为参数的读取器读取所有底层数据,并忽略 io.EOF 错误。
实际上,当碰到 io.EOF 错误时,该函数就会返回读到的所有数据,这正是 data 字段所代表的数据。另外,*myMultipleReader 应该作为 MultipleReader 接口的实现类型。对于后者声明的唯一方法,其实现极其简单:
func (rr *myMultipleReader) Reader() io.ReadCloser { return ioutil.NopCloser(bytes.NewReader(rr.data)) }bytes.NewReader 函数的作用是根据参数生成并返回一个 *bytes.Reader 类型的值。
*bytes.Reader 类型是 io.Reader 接口的一个实现类型,不过我们这里需要的是 io.ReadCloser 接口类型的值。所以,需要使用 ioutil.NopCloser 函数对这个 *bytes.Reader 类型的值进行简单的包装。ioutil.NopCloser 函数会返回一个 io.ReadCloser 类型的值。
之前说过,io.ReadCloser 接口只比 io.Reader 多声明了一个 Close 方法,这个 Close 方法没有参数声明,但有一个 error 类型的结果声明。然而,ioutil.NopCloser 函数的结果值的 Close 方法永远只会返回 nil。也正因为如此,我们常常用这个函数包装无需关闭的读取器,这就是 NopCloser 的含义。
多重读取器的 Reader 方法总是返回一个新的可关闭读取器。因此,我可以利用它多次读取底层数据,并可以用该方法的结果值替代原先的 HTTP 响应的 Body 字段值很多次,这也是“多重”的真正含义。
所有教程
- socket
- Python基础教程
- C#教程
- MySQL函数
- MySQL
- C语言入门
- C语言专题
- C语言编译器
- C语言编程实例
- GCC编译器
- 数据结构
- C语言项目案例
- C++教程
- OpenCV
- Qt教程
- Unity 3D教程
- UE4
- STL
- Redis
- Android教程
- JavaScript
- PHP
- Mybatis
- Spring Cloud
- Maven
- vi命令
- Spring Boot
- Spring MVC
- Hibernate
- Linux
- Linux命令
- Shell脚本
- Java教程
- 设计模式
- Spring
- Servlet
- Struts2
- Java Swing
- JSP教程
- CSS教程
- TensorFlow
- 区块链
- Go语言教程
- Docker
- 编程笔记
- 资源下载
- 关于我们
- 汇编语言
- 大数据
- 云计算
- VIP视频