io重要的接口

在介绍buffer之前,先来认识两个重要的接口,如下边所示:

type Reader interface {
Read(p []byte) (n int, err error)
} type Writer interface {
Write(p []byte) (n int, err error)
}

  

上边两个接口在golang sdk安装目录src/io/io.go中定义。后边凡是涉及到io相关操作的,基本上都实现了这两个接口,如:

1. package bufio 中的Reader类
2. package bytes 中的Reader类与Buffer类
3. package os 中 的File类,这个实现的最为复杂,主要由于在文件操作中,需要系统底层提供服务。
...不再一一列举...

  

经常听说有这么一句话:“使用I/O buffer,有助于提高效率”。但是,我想反问的是,真的提高了效率了吗? 
buffer在什么情况下会提高我们的程序性能呢?带着这个问题,我们来剖析一下上边提到的几个类。

1.第一个类bytes.Reader

这个类,实现了io.Reader接口,但是这个类没有实现io.Writer接口。这个类没有buffer,为啥?因为这个类,在初始化时,将字符流传入到对象中保存,没有提供Write方法写入新的字符流。所以,这个类不需要buffer。

2.第二个类bytes.Buffer

这个类实现了io.Reader与io.Writer接口,这个类在写入字节流的过程中,使用到了buffer,怎么实现的呢? 
在初始化这个类时,会传入一个[]byte类型的slice到对象中,当Write方法向这个对象中写入字节流时,如果之前传入的这个[]byte申请的空间不够时,Write会调用自身的Grow方法,给这个[]byte类型的slice类型扩容,这样,这个里边的buffer会随着写入量增大,长度会不断的扩大。如果此处没有buffer的话,当写入容量满时,要么阻塞,要么循环写入,这样会导致系统卡死或数据被破坏,当引入buffer后,解决了上边的两个问题。但是这种解决方式,存在一个隐患,也就是如果出现读取死循环,这样会造成内存溢出。

3.第三个类bufio.Reader

这个类实现了io.Reader接口,这个类在实例化时,需要传入一个io.Reader类型的变量,这问题就来了,一个io.Reader类型的变量,一定是实现了Read方法了,那么为什么还需要装进bufio.Reader对象中呢?原来,bufio.Reader类中得Read方法,在读取字节流时,对传入的[]byte类型变量空间长度进行检查,如果传入变量的长度小于bufio.Reader初始化的容量,将会首先调用io.Reader自己的Read方法,将内容写入到bufio.Reader对象的buffer中,然后将值复制给传入的[]byte变量。这样做的好处是,在执行io.Reader的Read方法时,多读取一些字节,这样对于像文件操作就大有裨益。

4.第四个类os.File

这个类实现了io.Writer与io.Reader类,但是有点特殊的是,os.File的Read方法与Write均需要借助于系统层面的文件操作方法.总所周知,在文件读取时,Read与Write方法时没有缓存的,也就是你读几个字节,取决于你传入的变量容量是多少,如果容量为1,那么对于文件读取而言,就会很慢,所以将os.File的对象,传入到bufio.Reader对象中,这样可以在某些程度上提高效率,哪些时候呢?就是你在调用Read方法时,传入的变量容量太小时,会提高读取效率.但是bufio.Reader提供的Read方法不能保证每次读到的字符数一致,这个与其实现方式有关,但是不影响我们使用,只要确保收到EOF,再停止读取即可.

总结 
在使用I/O操作时,bufio包提供了带buffer的方式读取I/O流,在操作文件读取,报文读取等上,可以在某种程度上提高效率,bufio中的类,并没有从底层实现Read与Write方法,只是限定了最小读取量.这个最小量就是bufio.Reader初始化长度. 
bytes.Buffer提供的buffer十分强大,这个类不仅实现了io.Reader接口,还实现了io.Writer接口.所以bytes.Buffer的对象不仅可以读取,还可以追加写入,写入的过程中,容量还可以自动扩展,所以,功能十分强大.但是在使用时,要注意安全,bytes.Buffer会不断的扩大,扩大,最终还会panic.

关于golang中IO相关的Buffer类浅析的更多相关文章

  1. Java IO体系之File类浅析

    Java IO体系之File类浅析 一.File类介绍 位于java.io下的Java File类以抽象的方式代表文件名和目录路径名.该类主要用于文件和目录的创建.文件的查找和文件的删除等.File对 ...

  2. java在文本处理中的相关辅助工具类

    1,java分词 package com.bobo.util; import ICTCLAS.I3S.AC.ICTCLAS50; public class Cutwords { public stat ...

  3. java中IO写文件工具类

    以下是一些依据经常使用java类进行组装的对文件进行操作的类,平时,我更喜欢使用Jodd.io中提供的一些对文件的操作类,里面的方法写的简单易懂. 当中jodd中提供的JavaUtil类中提供的方法足 ...

  4. Java中Io流操作-File类的常用操作-创建文件,创建文件夹

    package com.hxzy.IOSer; import java.io.File;import java.io.IOException; public class Demo03 { public ...

  5. golang中使用mongodb的操作类以及如何封装

    mgo简介 mongodb官方没有关于go的mongodb的驱动,因此只能使用第三方驱动,mgo就是使用最多的一种. mgo(音mango)是MongoDB的Go语言驱动,它用基于Go语法的简单API ...

  6. C++的IO处理中的头文件以及类理解(2)<sstream>头文件

    C++的IO处理中的头文件以及类理解(2)<sstream>头文件 头文件<sstream>中定义的类型都继承iostream头文件中定义的类型.除了继承得来的操作,sstre ...

  7. golang io中io.go解读

    目录 1. 整体大纲 2. 接口 读 写 关闭 寻址 3. 函数 读 写 复制 4. 结构体 SectionReader LimitedReader teeReader 5. 备注 根据golang ...

  8. 在 go/golang语言中使用 google Protocol Buffer

    怎么在go语言中实用google protocol Buffer呢? 现在的潮流趋势就是一键搞定,跟ubuntu安装软件一样 go get code.google.com/p/goprotobuf/{ ...

  9. golang中接口interface和struct结构类的分析

    再golang中,我们要充分理解interface和struct这两种数据类型.为此,我们需要优先理解type的作用. type是golang语言中定义数据类型的唯一关键字.对于type中的匿名成员和 ...

随机推荐

  1. 公用表表达式(CTE) with as

    在编写T-SQL代码时,往往需要临时存储某些结果集.前面我们已经广泛使用和介绍了两种临时存储结果集的方法:临时表和表变量.除此之外,还可以使用公用表表达式的方法.公用表表达式(Common Table ...

  2. [算法竞赛][2018][蓝桥杯][LanqiaoCA]第九届蓝桥杯A组

    题目1 标题:分数 1/1 + 1/2 + 1/4 + 1/8 + 1/16 + .... 每项是前一项的一半,如果一共有20项,求这个和是多少,结果用分数表示出来.类似:3/2当然,这只是加了前2项 ...

  3. Ajax -02 -JQuery+Servlet -实现页面点击刷出表格数据

    demo功能分析 jquery 的js文件需要导入,json的三个文件需要导入,不然writeValueAsString 会转化成JsonArray(json 数组)失败 $("#mytbo ...

  4. top命令定位CPU高占用代码

    步骤如下: 1.使用top命令定位异常进程.可以看见12836的CPU和内存占用率都非常高 2.使用top -H -p 进程号查看异常线程 3.使用printf "%x\n" 线程 ...

  5. 题解 洛谷P3745 【[六省联考2017]期末考试】

    这题有点绕,我写了\(2h\)终于搞明白了. 主要思路:枚举最晚公布成绩的时间\(maxt\),然后将所有公布时间大于\(maxt\)的课程都严格降为\(maxt\)即可. 在此之前,还要搞清楚一个概 ...

  6. Python爬取网页信息

    Python爬取网页信息的步骤 以爬取英文名字网站(https://nameberry.com/)中每个名字的评论内容,包括英文名,用户名,评论的时间和评论的内容为例. 1.确认网址 在浏览器中输入初 ...

  7. 物体检测方法(1) - YOLO 详解

    最近遇到一些卡证识别的检测问题,打算先把理论知识梳理一下,随后还会梳理一版代码注释. 以前的region+proposal来检测的框架,这一系列速度和精度不断提高,但是还是无法达到实时.存在的主要问题 ...

  8. python 赋值与深浅拷贝

    https://www.cnblogs.com/Eva-J/p/5534037.html

  9. 域渗透:IPC$ 命名管道

    介绍:IPC$(Internet Process Connection) 是共享 " 命名管道 " 的资源,它是为了让进程间通信而开放的命名管道,通过提供可信任的用户名和口令,连接 ...

  10. Kafka、ActiveMQ、RabbitMQ、RocketMQ区别

    1.区别: Kafka和RocketMQ的区别: 1.两者对于消息的单机吞吐量.时效性.可用性.消息可靠性都差不多,其中时效性就是消息延迟都在ms级,kafka吞吐量会更大. 2.功能支持方面:Kaf ...