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. 铁力项目mysql异常处理过程记录

    地区:铁力 故障:2019-06-26 10:19:34 139921514837760 [ERROR] mysqld: Error writing file 'mysql-bin' (errno: ...

  2. Maven01-maven打包Web项目成war文件-tomcat脱机运行启动项目

    1 执行package 2 复制 3 catalina run  ,打开cmd窗口 4 输入网址 5注意要配置tomcat的 Application context为工程名字

  3. python中的logging日志模块

    日志是程序不可或缺的一部分.它可以记录程序的运行情况,帮助我们更便捷地发现问题,而python中的logging日志模块给我们提供了这个机会. logging给我们提供了五种函数用来输出日志:debu ...

  4. postgresql —— 表的继承

    示例: CREATE TABLE cities ( --父表 name text, population float, altitude int ); CREATE TABLE capitals ( ...

  5. 使用session存储数据

    @WebServlet("/reply") public class ReplyServlet extends HttpServlet { @Override protected ...

  6. CocoaPods加载第三方库

    http://code4app.com/article/cocoapods-install-usage

  7. 洛谷 P816 忠诚 题解

    每日一题 day28 打卡 Analysis 这道题用线段树维护区间最小值很简单,因为没有修改所以连lazy_tag都不用,但是这道题可以用树状数组维护区间最小值,非常骚气. 线段树代码: #incl ...

  8. webuploader如何实现分片+断点续传

    javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 ajax向后端发请求 1. 通过form表单向后端发送请求 <form id=&quo ...

  9. LIO -SCSI target

    2010年底,LIO 项目获选成为新的内核态的 SCSI target,取代原有的用户态的 STGT 项目.当时有两个主要的竞争项目(LIO和SCST),都在努力将代码并入主线内核.本文将比较着两个项 ...

  10. 《挑战30天C++入门极限》C++的iostream标准库介绍(1)

        C++的iostream标准库介绍(1) 我们从一开始就一直在利用C++的输入输出在做着各种练习,输入输出是由iostream库提供的,所以讨论此标准库是有必要的,它与C语言的stdio库不同 ...