侯体宗的博客
  • 首页
  • Hyperf版
  • beego仿版
  • 人生(杂谈)
  • 技术
  • 关于我
  • 更多分类
    • 文件下载
    • 文字修仙
    • 中国象棋ai
    • 群聊
    • 九宫格抽奖
    • 拼图
    • 消消乐
    • 相册

GO语io包的常用接口

Go  /  管理员 发布于 4年前   204

本文实例分析了GO语io包的常用接口。分享给大家供大家参考。具体分析如下:

我没有 C/C++ 基础,没有接口的概念,且从 Python 投奔而来,Python 的极简主义(一个结果往往只提供一个方法),让我在 Golang 中非常迷糊,特别是文件的读写操作,因为 Go 的文件读写操作有很多的方法,让我不知道怎么选择。直到我学习了 interface 的概念,然后由看了 package io 后才慢慢理解,也渐渐的喜欢上了 Golang 的灵活性。以我的经验来说,接口是一个很重要的知识点,是一系列操作的规范,特别是公共接口尤为重要,如:package io

本文仅仅列举最常用的几个接口,如果您想系统的学习 io 接口,建议阅读底部参考链接。

一、IO 接口概述

package os 提供了对 I/O 原语的基本接口,使之成为共享的公共接口,这些公共接口抽象出了泛用的函数并附加了一些相关的原语的操作。因为这些接口和原语是对底层实现完全不同的低水平操作的包装,除非得到其它方面的通知,客户端不应假设它们是并发执行安全的。

在 package os 中最重要的是两个接口:Reader 和 Writer 接口。本章所提到的各种接口,都跟这两个接口有关,也就是说,只要实现了这两个接口,它就有了 IO 的功能。

小贴士:

var EOF = errors.New("EOF"): 在 package io中定义,使用非常频繁。正常情况下当 Read() 无法得到更多返回时就返回 EOF,即文件到达了结尾(end-of-file)。

二、io.Reader 和 io.Writer

定义:
复制代码 代码如下:type Reader interface {
    Read(p []byte) (n int, err error)
}

type Writer interface {
    Write(p []byte) (n int, err error)
}
Read 将 len(p) 个字节读取到 p 中,当遇到任何错误(包括EOF)会立即返回已读取的字节数,函数结束会返回成功读取的字节数和任何错误。
Write 将 len(p) 字节数据从 p 写入底层的数据流,然后返回成功写入的字节数和任何错误。

从接口名称很容易猜到,一般地,Go中接口的命名约定:接口名以er结尾。注意,这里并非强行要求,你完全可以不以 er 结尾。标准库中有些接口也不是以 er 结尾的。
示例:
复制代码 代码如下:func wr() {
 f, _ := os.Create("at.txt")
 defer f.Close()
 f.Write([]byte("Go是一种令人愉悦的编程语言")) //写入字节流
 f.Seek(0, os.SEEK_SET)            //将指针重置

 p := make([]byte, 2) // 读取 2 byte( len(buf)=2 )
 if _, err := f.Read(p); err != nil {
  log.Fatal("[F]", err)
 }
 fmt.Printf("读取字符 \"%s\", 长度为 %d byte\n", p, len(p))

 p = make([]byte, 50)
 if _, err := f.Read(p); err != nil {
  if err != io.EOF { //忽略 EOF 错误
   log.Fatal("[F]", err)
  }
 }
 fmt.Printf("读取字符 \"%s\", 长度为 %d byte\n", p, len(p))
}
读取字符 "Go", 长度为 2 byte
读取字符 "是一种令人愉悦的编程语言              ", 长度为 50 byte

三、io.ReaderAt 和 os.WriterAt

定义(off 是 offset 的缩写):
复制代码 代码如下:type ReaderAt interface {
    ReadAt(p []byte, off int64) (n int, err error)
}

type WriterAt interface {
    WriteAt(p []byte, off int64) (n int, err error)
}
ReadAt() 从基本输入源的偏移量 off 处开始,其他和 Read() 一样;
WriteAt() 从基本输入源的偏移量 off 处开始,其他和 Write() 一样。

示例:
复制代码 代码如下:func at() {
 f, _ := os.Create("at.txt")
 defer f.Close()

 f.WriteString("Go是一种令人愉悦的编程语言")
 f.WriteAt([]byte("程序"), 26) //偏移 26byte 改写“编程”->“程序”

 fi, _ := f.Stat()              //获取文件信息
 p := make([]byte, fi.Size()-2) //文件大小减去偏移值
 f.ReadAt(p, 2)                 //偏移 2 byte

 os.Stdout.Write(p)
}

四、io.ReaderFrom 和 os.WriterTo

定义:
复制代码 代码如下:type ReaderFrom interface {
    ReadFrom(r Reader) (n int64, err error)
}

type WriterTo interface {
    WriteTo(w Writer) (n int64, err error)
}
ReadFrom() 从 r 中读取数据,直到 EOF 或发生错误。返回读取的字节数和 io.EOF 之外的其他错误。ReadFrom不会返回EOF错误

WriteTo() 将数据写入 w 中,直到没有数据可写或发生错误。返回写入的字节数和任何错误。

示例:
复制代码 代码如下:func fromTo() {
 r := strings.NewReader("Go是一种令人愉悦的编程语言") //创建一个 Reader
 w := bufio.NewWriter(os.Stdout)          //创建一个 Writer

 w.ReadFrom(r) // w 一次性读取 r 的全部内容
 w.Flush()

 r.Seek(0, os.SEEK_SET) //重置指针

 r.WriteTo(w) // r 一次性将内容写入 w 中
 w.Flush()
}

五、io.Seeker

定义:
复制代码 代码如下:type Seeker interface {
    Seek(offset int64, whence int) (ret int64, err error)
}
Seek 设置下一次 Read 或 Write 的偏移量(offset),它的解释取决于 whence。示例见上文。

whence的值,在os包中定义了相应的常量:
复制代码 代码如下:SEEK_SET int = 0 //从文件的起始处开始设置 offset
SEEK_CUR int = 1 //从文件的指针的当前位置处开始设置 offset
SEEK_END int = 2 //从文件的末尾处开始设置 offset
六、io.Closer

定义:
复制代码 代码如下:type Closer interface {
    Close() error
}
用于关闭数据流,释放资源,不用多废话了吧。

七、其他
复制代码 代码如下:type ByteReader interface {
 ReadByte() (c byte, err error)
}

type RuneReader interface {
    ReadRune() (r rune, size int, err error)
}
ReadByte读取输入中的单个字节并返回。如果没有字节可读取,会返回错误。
ReadRune读取单个utf-8编码的字符,返回该字符和它的字节长度。如果没有有效的字符,会返回错误。
复制代码 代码如下:type ByteWriter interface {
    WriteByte(c byte) error
}
WriteByte写入一个字节,如果写入失败会返回错误。

参考:
https://gowalker.org/io
https://github.com/polaris1119/The-Golang-Standard-Library-by-Example/blob/master/chapter01/01.1.md

希望本文所述对大家的GO语言程序设计有所帮助。


  • 上一条:
    GO语言常用的文件读取方式
    下一条:
    GO语言文件的创建与打开实例分析
  • 昵称:

    邮箱:

    0条评论 (评论内容有缓存机制,请悉知!)
    最新最热
    • 分类目录
    • 人生(杂谈)
    • 技术
    • linux
    • Java
    • php
    • 框架(架构)
    • 前端
    • ThinkPHP
    • 数据库
    • 微信(小程序)
    • Laravel
    • Redis
    • Docker
    • Go
    • swoole
    • Windows
    • Python
    • 苹果(mac/ios)
    • 相关文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • 近期文章
    • 在go中实现一个常用的先进先出的缓存淘汰算法示例代码(0个评论)
    • 在go+gin中使用"github.com/skip2/go-qrcode"实现url转二维码功能(0个评论)
    • 在go语言中使用api.geonames.org接口实现根据国际邮政编码获取地址信息功能(1个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf分页文件功能(0个评论)
    • gmail发邮件报错:534 5.7.9 Application-specific password required...解决方案(0个评论)
    • 欧盟关于强迫劳动的规定的官方举报渠道及官方举报网站(0个评论)
    • 在go语言中使用github.com/signintech/gopdf实现生成pdf文件功能(0个评论)
    • Laravel从Accel获得5700万美元A轮融资(0个评论)
    • 在go + gin中gorm实现指定搜索/区间搜索分页列表功能接口实例(0个评论)
    • 在go语言中实现IP/CIDR的ip和netmask互转及IP段形式互转及ip是否存在IP/CIDR(0个评论)
    • 近期评论
    • 122 在

      学历:一种延缓就业设计,生活需求下的权衡之选中评论 工作几年后,报名考研了,到现在还没认真学习备考,迷茫中。作为一名北漂互联网打工人..
    • 123 在

      Clash for Windows作者删库跑路了,github已404中评论 按理说只要你在国内,所有的流量进出都在监控范围内,不管你怎么隐藏也没用,想搞你分..
    • 原梓番博客 在

      在Laravel框架中使用模型Model分表最简单的方法中评论 好久好久都没看友情链接申请了,今天刚看,已经添加。..
    • 博主 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 @1111老铁这个不行了,可以看看近期评论的其他文章..
    • 1111 在

      佛跳墙vpn软件不会用?上不了网?佛跳墙vpn常见问题以及解决办法中评论 网站不能打开,博主百忙中能否发个APP下载链接,佛跳墙或极光..
    • 2016-10
    • 2017-09
    • 2020-03
    • 2020-05
    • 2020-06
    • 2020-07
    • 2020-12
    • 2021-01
    • 2021-05
    • 2021-06
    • 2021-07
    • 2021-08
    • 2021-10
    • 2021-11
    • 2021-12
    • 2022-01
    • 2022-02
    • 2022-03
    • 2022-04
    • 2022-05
    • 2022-06
    • 2022-07
    • 2022-08
    • 2022-09
    • 2022-10
    • 2022-11
    • 2022-12
    • 2023-01
    • 2023-02
    • 2023-03
    • 2023-04
    • 2023-05
    • 2023-06
    • 2023-07
    • 2023-08
    • 2023-09
    • 2023-10
    • 2023-11
    • 2023-12
    • 2024-01
    • 2024-02
    • 2024-03
    • 2024-04
    • 2024-05
    • 2024-06
    • 2024-07
    • 2024-08
    • 2024-11
    • 2025-02
    • 2025-04
    • 2025-05
    • 2025-06
    Top

    Copyright·© 2019 侯体宗版权所有· 粤ICP备20027696号 PHP交流群

    侯体宗的博客