IO

  • IO包 是对数据流的操作。从哪里来, 怎么处理,再到哪里去。

图片来源 https://medium.com/learning-the-go-programming-language/streaming-io-in-go-d93507931185

  • IO包 对数据的读写 是通过接口的形式约定的。数据的来源或者去向可能是 网络,内存,文件。
type Reader interface {
Read(p []byte) (n int, err error)
} type Writer interface {
Write(p []byte) (n int, err error)
}
  • 应用层 只需要按照接口去调用接口 不用关心底层实现细节 非常方便
package main

import (
"io"
"net/http"
"os"
"strings"
) type R struct {
reader io.Reader
} func NewReader(r io.Reader) *R {
return &R{
reader: r,
}
} func (r *R) Read(p []byte) (n int, err error) {
if _, err = r.reader.Read(p); err != nil {
return
}
return len(p), nil
} func main() {
netR, err := http.Get("https://www.bilibili.com/")
if err != nil {
panic(err)
}
defer netR.Body.Close()
fileR, err := os.Open("/tmp/data.txt")
if err != nil {
panic(err)
}
//读内存
r1 := NewReader(strings.NewReader(""))
b := make([]byte, 10*1024)
if _, err := r1.Read(b); err != nil {
panic(err)
}
//读网络
r2 := NewReader(netR.Body)
if _, err := r2.Read(b); err != nil {
panic(err)
}
//读文件
r3 := NewReader(fileR)
if _, err := r3.Read(b); err != nil {
panic(err)
}
}

bufio

  • 每次对磁盘的写入或者发起网络请求 都会给系统带来压力。

    将多次操作合并为一次 会减轻系统的压力
  • 更优的流程是 producer --> buffer -->io.Writer

参考:https://medium.com/golangspec/introduction-to-bufio-package-in-golang-ad7d1877f762

func buffer() {
fmt.Println("IO")
w := new(W)
w.Write([]byte{'1'})
w.Write([]byte{'2'})
w.Write([]byte{'3'})
w.Write([]byte{'4'}) fmt.Println("Buffer IO")
bw := bufio.NewWriterSize(w, 3)
bw.Write([]byte{'1'})
bw.Write([]byte{'2'})
bw.Write([]byte{'3'})
bw.Write([]byte{'4'})
err := bw.Flush()
if err != nil {
panic(err)
}
} type W struct {
} func (*W) Write(p []byte) (n int, err error) {
fmt.Println("length is ", len(p))
fmt.Println(string(p))
return len(p), nil
}
  • 普通的IO操作 会直接输出
  • buffio 则会首先收集数据到缓存中 等判断buffer满了

    之后才会一次性将缓存中的数据 输出。缓存中可能有多余的数据

    所以需要 最后单独调用flush 函数 强制将未满的缓存 输出

ReadFrom

  • 写操作之前需要 读取数据。io.ReaderFrom interface 就是

    为了更加方便的 从一个reader中读取数据
type ReaderFrom interface {
ReadFrom(r Reader) (n int64, err error)
}
func ReadFrom() {
sr := strings.NewReader("read from strings reader")
w := new(W)
bw := bufio.NewWriterSize(w, 6)
if _, err := bw.ReadFrom(sr); err != nil {
panic(err)
}
if err := bw.Flush(); err != nil {
panic(err)
}
}
  • bufio.Writer实现了这个接口 从reader中读取数据 io.reader -> buffer -> io.writer

ReadSlice

  • 如果bufio的NewReaderSize 如果小于16个字符 会设置为默认长度16个字符
  • 读取过程中 会优先判断buffer的size是否足够大 不够的话就会抛出 bufio: buffer full错误
  • bufio的ReadSlice函数可以读取读取指定字符之前的字符串,如果读到字符串末尾,还没有找到指定字符串

    则会返回eof
	s := strings.NewReader("abc|defg\nhij")
r := bufio.NewReader(s)
b, err := r.ReadSlice('|')
if err != nil {
panic(err)
}
fmt.Println(string(b)) b, err = r.ReadSlice('\n')
if err != nil {
panic(err)
}
fmt.Println(string(b))

Go IO && bufio的更多相关文章

  1. go 文件操作 io

    package main import ( "fmt" "os" ) func main() { //打开文件 //概念说明: file 的叫法 //1. fi ...

  2. go 常用包

    标准的 Go 代码库中包含了大量的包,并且在安装 Go 的时候多数会伴随一起安 装.浏览 $GOROOT/src/pkg 目录并且查看那些包会非常有启发. fmt:包 fmt 实现了格式化的 I/O ...

  3. go linux 学习记录

    1 yum install mercurial 安装mercurial包 2 yum install git 安装git包 3 yum install gcc 安装gcc 4  然后就可以下载gola ...

  4. 使用GO语言灵活批量ssh登录服务器执行操作

    摘要: 在工作中时常需要登录服务器做一系列操作,每次输入ssh xxx总是很麻烦.这时候为什么不考虑写一个通用的小脚本呢? go语言是一门新兴语言,能够在很多地方发挥总用.初学go语言,做了这么一个小 ...

  5. GO语言的进阶之路-网络编程之socket

    GO语言的进阶之路-网络编程之socket 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是socket; 在说socket之前,我们要对两个概念要有所了解,就是IP和端口 ...

  6. Go 中包导入声明

    Go中的程序由软件包组成.通常,软件包依赖于其他软件包,或者内置于标准库或第三方的软件包.包需要先导入才能使用其导出的标识符.本文将翻译一篇国外的文章,用于介绍包导入的原理以及几种常用的导入方式. & ...

  7. Go_18: Golang 中三种读取文件发放性能对比

    Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提 ...

  8. Golang 中三种读取文件发放性能对比

    Golang 中读取文件大概有三种方法,分别为: 1. 通过原生态 io 包中的 read 方法进行读取 2. 通过 io/ioutil 包提供的 read 方法进行读取 3. 通过 bufio 包提 ...

  9. Go 语言为Fibonacci函数实现Read方法

    Go语言非常灵活,只要为对象实现了相应的方法就可以把他看成实现了某个接口,类似于Durk Type, 为Fibonacci实现Read方法,就可以像读取文件一样,去读取下一个Fibonacci值. 示 ...

随机推荐

  1. Codeforces 185D(发现性质、欧拉定理)

    学到的东西 不知道gcd时不妨先假设为d,然后为了满足全部式子说不定可以得到d的取值范围. 幂上带幂考虑欧拉定理的使用. 有几个特殊情况会破坏公式的完美不要紧,看看特殊情况是否能简便地判定. 连乘公式 ...

  2. NET Core断点续传

    .NET Core断点续传   ASP.NET Core断点续传 在ASP.NET WebAPi写过完整的断点续传文章,目前我对ASP.NET Core仅止于整体上会用,对于原理还未去深入学习,由于有 ...

  3. 爬虫(Xpath)——爬tieba.baidu.com

    工具:python3 核心知识点: 1)lxml包不能用pip下载,因为里面有其他语言编写的文件 2)urlopen返回的请求是html文件,要使用 content = etree.HTML(html ...

  4. (转)网站DDOS攻击防护实战老男孩经验心得分享

    网站DDOS攻击防护实战老男孩经验心得分享 原文:http://blog.51cto.com/oldboy/845349

  5. nginx的基本操作

    启动 nginx -c /etc/nginx/nginx.conf停止nginx -s stop nginx -s quit pkill -9 nginx重载nginx -s reload文件检测ng ...

  6. js 回车提交表单

    一.整个页面用一个回车提交事件: <input type="button" value="回车提交" id="auto" onclic ...

  7. sql常用操作(一)

    sql(structured query language,结构化查询语言)语言:和数据库交互的语言,进行数据库管理的语言. 1.1 sql语句的作用:说白了就是增删改查 管理数据库 管理表 管理数据 ...

  8. 1044 拦截导弹 1999年NOIP全国联赛提高组 个人博客:attack.cf

    1044 拦截导弹 1999年NOIP全国联赛提高组 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold         题目描述 Description 某国为了防御敌 ...

  9. AngularJS中最重要的核心功能

    以下是AngularJS中最重要的核心功能: 数据绑定: 模型和视图组件之间的数据自动同步. 适用范围: 这些对象参考模型.它们充当控制器和视图之间的胶水. 控制器: 这些Javascript函数绑定 ...

  10. HBase数据模型(1)

    HBase数据模型(1) HBase数据模型(2) 1.0 HBase的特性 Table HBase以表(Table)的方式组织数据,数据存储在表中. Row/Column 行(Row)和列(Colu ...