当前位置: 移动技术网 > IT编程>脚本编程>Go语言 > GO语io包的常用接口

GO语io包的常用接口

2017年12月12日  | 移动技术网IT编程  | 我要评论
本文实例分析了go语io包的常用接口。分享给大家供大家参考。具体分析如下: 我没有 c/c++ 基础,没有接口的概念,且从 python 投奔而来,python 的极简主

本文实例分析了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语言程序设计有所帮助。

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网