首页 > 其他分享 >Go标准库学习:io库

Go标准库学习:io库

时间:2023-12-20 16:44:55浏览次数:29  
标签:io err error 学习 int64 func Reader Go type

io库

io中包括了常用的io流中的函数,并依靠这些函数定义了常用的接口和接口组合。我觉得这是最重要的。


常量(Constants)

const (
  SeekStart = 0   // 定位到文件头 
  SeekCurrent = 1 // 定位到当前读写的位置
  SeekEnd = 2     // 定位到文件尾
)

都是用于在文件读写时进行定位的常量,相当于C库中的SEEK_STARTSEEK_SETSEEK_END

变量(Variables)

var EOF = errors.New("EOF")

表示读到了文件结尾。

需要注意的是,返回EOF时只能直接返回io库中定义的这个变量,因为在进行EOF的判断时,会直接将返回的error和EOF进行比较(==)。

var ErrClosedPipe = errors.New("io: read/write on closed pipe")

在关闭了的Pipe上进行了读或者写

var ErrNoProgress = errors.New("multiple Read calls return no data or error")

一个Reader被多个调用方调用,通常意味着该Reader损坏了。

var ErrShortWrite = errors.New("short write")

读取到了少于请求的数量的字节,但又返回不了一个明确的错误。

var ErrUnexpectedEOF = errors.New("unexpected EOF")

当读取一个固定长度的数据块或者一个结构时,读到中间读到了意料之外的EOF。

接口 (interfaces)

读取和写入

io库中定义了很多常用的接口,涉及输入输出的类都应当遵循这些接口。

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

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

type ByteReader interface {
	ReadByte() (byte, error)
}

type ByteWriter interface {
	WriteByte(c byte) error
}

// 读出一个Rune,返回该码点和该码点的字节长度
type RuneReader interface {
	ReadRune() (r rune, size int, err error)
}

最常用的就是读写函数,分别是ReaderWriter,分别读取和写入slice字节,并返回读取和写入的字节数。

类似的是ByteReaderByteWriter,分别读取和写入一个字节。RuneReader读出一个unicode码点,但没有RuneWriter

其他IO相关的接口

// 从偏移off处读取len(p)字节至p。返回读取的字节或者发生的错误。0 <= n <= len(p)
// 1. n < len(p)时,函数会返回一个非nil的err,解释为什么只读取了n个字节。
//      如果可用的数据不足len(p),ReadAt会阻塞,直到读完了或者发生了错误。
// 2. 如果n == len(p),返回的err == nil 或者err == io.EOF
// 如果这个函数在某个支持Seek的结构体内,Seek设置的偏移不应该影响本函数。
type ReaderAt interface {
	ReadAt(p []byte, off int64) (n int, err error)
}

// 将数据写入到w中(使用Writer的Write()方法)
type WriterTo interface {
	WriteTo(w Writer) (n int64, err error)
}

// 从r中读取数据(使用Reader的Read()方法)
type ReaderFrom interface {
	ReadFrom(r Reader) (n int64, err error)
}

// 将写一个String
type StringWriter interface {
	WriteString(s string) (n int, err error)
}

// 在off写数据
type WriterAt interface {
	WriteAt(p []byte, off int64) (n int, err error)
}

// 在指定位置进行读或者写
//  offset是一个有符号整数,whence有三个可选值:io.SeekStart, io.SeekCurrent, io.SeekEnd
type Seeker interface {
	Seek(offset int64, whence int) (int64, error)
}

// 关闭输入输出流
type Closer interface {
	Close() error
}

这部分是其他的IO相关的接口,包括:从某个位置读写、从其他流读出或写入、定位流、关闭等。

组合接口成为新接口

// 同时支持ReadByte()和UnreadByte()
type ByteScanner interface {
	ByteReader
	UnreadByte() error
}

// 同时支持ReadRune()和UnreadRune()
type RuneScanner interface {
	RuneReader
	UnreadRune() error
}

// 同时有Read和Close
type ReadCloser interface {
	Reader
	Closer
}

// 同时有Read、Seek
type ReadSeeker interface {
	Reader
	Seeker
}

// 同时有Read、Seek和Close 
type ReadSeekCloser interface {
	Reader
	Seeker
	Closer
}

// 同时有Read和Write
type ReadWriter interface {
	Reader
	Writer
}

// 同时有Read、Write和Seek
type ReadWriteSeeker interface {
	Reader
	Writer
	Seeker
}

// 同时有Read、Write和Close
type ReadWriteCloser interface {
	Reader
	Writer
	Closer
}

这部分主要是将各个单一函数的接口进行组合(或者扩展)。

函数 (Functions)

拷贝

func Copy(dst Writer, src Reader) (written int64, err error)
func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
func CopyN(dst Writer, src Reader, n int64) (written int64, err error)

将数据从src写入到dst。如果dst支持ReadFrom的话则使用该API。

需要注意的是,如果拷贝成功的话,返回的err == nil,而不是io.EOF.

读取

func ReadAll(r Reader) ([]byte, error)
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
func ReadFull(r Reader, buf []byte) (n int, err error)

读取功能。

Pipe

func Pipe() (*PipeReader, *PipeWriter)

对应于Linux中的pipe接口,创建一个输入流和输出流,写到输出流中的数据可以从输入流中读出。

PipeReader

type PipeReader struct {
	// contains filtered or unexported fields
}

func (r *PipeReader) Close() error
func (r *PipeReader) CloseWithError(err error) error
func (r *PipeReader) Read(data []byte) (n int, err error)

可以读取、关闭、关闭并给Writer返回一个错误。

Close()后如果另一端再写会返回io.ErrClosedPipe. 而CloseWithError后如果另一端再写会返回传入的err。

Read()时如果另一端关闭了则会返回io.EOF.

PipeWriter

type PipeWriter struct {
	// contains filtered or unexported fields
}

func (w *PipeWriter) Close() error
func (w *PipeWriter) CloseWithError(err error) error
func (w *PipeWriter) Write(data []byte) (n int, err error)

PipeReader有着类似的函数,只不过当写端调用Close()时,对应的Reader端读取时返回io.EOF

其他

func WriteString(w Writer, s string) (n int, err error)

有StringWriter了还要有个内置的WriteString函数,看来写字符串很常用啊。

生成接口类型的函数

func NopCloser(r Reader) ReadCloser

生成一个ReaderCloser,该ReaderCloserRead()方法来自传入的ReaderClose()方法是一个nop(没有操作)。

func MultiReader(readers ...Reader) Reader
func TeeReader(r Reader, w Writer) Reader

MultiReader将多个Reader组合,读取时前一个Reader到了EOF就继续从下一个Reader读。

func MultiWriter(writers ...Writer) Writer

MultiWriter类似。

结构 (Structures)

type LimitedReader struct {
	R Reader // underlying reader
	N int64  // max bytes remaining
}
func LimitReader(r Reader, n int64) Reader
func (l *LimitedReader) Read(p []byte) (n int, err error)

限制最多读取N个字节。LimitReader()生成一个新的LimitReader结构。

type OffsetWriter struct {
	// contains filtered or unexported fields
}

func NewOffsetWriter(w WriterAt, off int64) *OffsetWriter

func (o *OffsetWriter) Seek(offset int64, whence int) (int64, error)
func (o *OffsetWriter) Write(p []byte) (n int, err error)
func (o *OffsetWriter) WriteAt(p []byte, off int64) (n int, err error)

OffsetWriter能够从指定的偏移处进行写。

NewOffsetWriter()创建一个新的OffsetWriter

Seek()设置偏移;Write()进行写入;WriteAt()在指定偏移进行写入,该方法不受位置影响,都是从初始位置开始计算偏移。

type SectionReader struct {
	// contains filtered or unexported fields
}

func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
func (s *SectionReader) Read(p []byte) (n int, err error)
func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
func (s *SectionReader) Size() int64

roff开始读取,最多读n个就到EOF

标签:io,err,error,学习,int64,func,Reader,Go,type
From: https://www.cnblogs.com/lycpp/p/17916926.html

相关文章

  • vue3学习笔记(四)
    表单输入绑定<!--文本(Text)--><inputv-model="message"placeholder="editme"/><p>Messageis:{{message}}</p><!--多行文本(Textarea)--><textareav-model="message"placeholder="addmultipl......
  • 无涯教程-Go - 错误处理
    Go编程提供了一个非常简单的错误处理框架,具有以下声明的内置错误接口类型-typeerrorinterface{Error()string}函数通常返回错误作为最后的返回值,使用errors.New构造基本的错误消息,如下所示:funcSqrt(valuefloat64)(float64,error){if(value<0){re......
  • Collections工具类的使用
    packagebackend02;//Collections工具类的使用importjava.util.ArrayList;importjava.util.Collections;publicclassPractice07{publicstaticvoidmain(String[]args){ArrayList<String>list=newArrayList<>();//语法格式:......
  • 爬虫-今日头条我的收藏-增量式导入到mongodb(三)
    背景:续接前文,当我们有了原始数据之后,自然会想如何利用这些数据。这些文件数据都是json格式,打开一个文本文件眼睛都要看花。所以想把这些数据导入到对应的数据库中,市面上几乎所有数据库都支持json格式存储。随着时间的推移,用户不断有新的收藏,这样就不断产生新的收藏文件。需要不......
  • 《Learning Transferable Visual Models From Natural Language Supervision》论文学
    一、Abstract最先进的计算机视觉系统被训练用以预测一组预定的固定目标类别。这种受限的监督方式限制了它们的通用性和可用性,因为需要额外的标记数据来指定任何新的视觉概念。因此,直接从关于图像的原始描述文本中学习是一个有希望的替代方法,它利用了更广泛的因特网监督来源。我......
  • 【算法】K-means 算法学习
    fromnumpyimport*importpandasaspdimportmatplotlib.pyplotasplt#计算两点之间的欧式距离defdist(a,b):returnsqrt(sum((a-b)**2))#生成聚类中心defcreate_center(data,k,defaultPts=[0,3,6]):#固定的几个点作为聚类中心ifdefaultP......
  • Java IO 模型
    IO是个啥IO,是input/output的缩写,表面意思是输入/输出,描述计算机中数据流动的过程,实际上就是CPU、内存和外部进行数据交换的过程举个例子,某个进程要获取到数据的过程如下:1.请求:进程请求外部数据2.准备:缓冲区准备数据,通过磁盘或者网络读取数据到内核空的缓冲区3.拷贝:将数......
  • go的封装、继承与多态的使用
    目录一、封装1.1公有封装1.2私有封装1.2.1工厂函数解析1.2.2&与*指针使用描述1.3深度封装二、继承与多态2.1继承与多态案例2.1.1继承代码分析2.1.2结构体实例化2.1.3多态代码分析一、封装​ 在Go语言中,封装是一种将数据和操作数据的方法组织在一起的概念。封装的目的......
  • 无涯教程-Go - Range(范围)
    Range关键字在for循环中使用,以迭代数组,切片,通道或映射的项。Range关键字在for循环中使用,以迭代数组(Array),切片(Slice),通道(Channel)或映射(Map)的项,对于数组和切片,它以整数形式返回元素的索引。对于Map,它返回下一个键值对(key/value)的键(key)。Range范围返回一个或两个值,如......
  • 分类模型评估(混淆矩阵, precision, recall, f1-score)的原理和Python实现
    混淆矩阵当我们已经获取到一个分类模型的预测值,可以通过不同指标来进行评估。往往衡量二分类模型是基于以下的混淆矩阵概念:TruePositive:真实值为正、预测值为正(真阳性)FalsePositive:真实值为负、预测值为正(假阳性)FalseNegative:真实值为正、预测值为负(假阴性)TrueNegative......