【golang】看一看官方包io

时间:2025-02-26 07:58:22

这一部分type部分的内容比较多,整个官方包看过去其实函数什么的很多,我的方法是根据函数名记作用但是不记参数,我的第一门语言是js,所以很多科班的东西理解不是很到位,有些不懂的地方就抱歉了

第一部分 函数部分

Copy(dst Writer, src Reader) (written int64, err error)

// 从src缓存中拷贝到dst的writer之中,按照我的理解reader接口是让你读取的缓存,writer则是专门输出的接口
reader := ("我是你爸爸\n")
written, _ := (, reader) //拷贝之后直接在终端输出
("拷贝的字节数是:", written)//拷贝的字节数是: 16  一个汉字三个字节,换行符号算一个字节
("len:", ())   //读取完了,剩下来的长度就是0

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

// 大体作用还是拷贝,具体是什么作用还需要后续看
// 这边借用一下上面的written和reader
reader1 := ("hahaha\n")
buf := make([]byte, 1)
written, err := (, reader1, buf)
if err != nil {
		(err)
}
("拷贝的字节数是:", written)
("缓存下来的数据是", buf)
// 我其实没搞懂

CopyN(dst Writer, src Reader, n int64) (written int64, err error)

//copy的亲戚,只不过指定读取的字节
// On return, written == n if and only if err == nil 照我理解,返回值的written代表读取的字节数是没用的,理论上就是n,只有当错误的时候才有使用的价值
reader2 := ("some bitches\n")
(, reader2, 4) //终端输出some

// 比如这里我可以假设一个错误
reader3 := ("heha\n")
written, err = (, reader3, 6)
if err != nil {
	(err, written) //EOF 5
	// 上面只有5个字节,但我要读取6个,返回eof错误,并告诉我实际的读取数是5
}

ReadAll(r Reader) ([]byte, error)

// 看名字就知道,这是一个全部读取
reader4 := ("我们是*接班人")
buf1, _ := (reader4)
("buf1:", string(buf1)) //buf1: 我们是*接班人

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

// 至少读取,逻辑上说也就是这个min必须<=buf的长度,否则报错 short buffer
reader5 := ("we will rock you")
buf2 := make([]byte, 5)
if n, err := (reader5, buf2, 5); err != nil {
		(n, err)
}
("buf2", string(buf2))
// 我们来看一下,如果reader本身的长度小于这个min会出现什么错误
reader6 := ("abc")
buf3 := make([]byte, 6)
if n1, err := (reader6, buf3, 4); err != nil {
	(n1, err) //3 unexpected EOF 意想不到的长度不足
}

ReadFull(r Reader, buf []byte) (n int, err error)

// 饱和读取,一定要读取len(buf)的长度
reader7 := ("abcd")
buf4 := make([]byte, 5)
_, err = (reader7, buf4)
if err != nil {
	(err)
}
(string(buf4)) //abcd reader长度不够的话明显就算了,unexpected EOF但是错误还是要报的

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

// 很简单,将s 写入一个 writer
// golang有很多同名的函数或者方法,一般按照相关功能去区分就可以
n2, _ := (, "是我,没想到吧\n")
("写入n2个字符", n2) //22

Pipe() (*PipeReader, *PipeWriter)

// 一个通道相关的读取写入函数
// 我觉得这个函数可能是channel的底层函数
r, w := ()
go func() {
	// 组织一下这个writer
	(w, "我是golang学习者")
	()
}()
if _, err = (, r); err != nil {
		(err)
}

第二部分 struct

 LimitedReader struct {
	R Reader // underlying reader
	N int64  // max bytes remaining
 }
// 明显是对读取的字节数进行了设置

func (l *LimitedReader) Read(p []byte) (n int, err error)
// 参数p应该是读取之后存放的位置
reader8 := ("今天就吃烤肉饭吧")

limit := {R: reader8,
	N: 6} //不这个写法的话会报错
buf5 := make([]byte, 7)
(buf5)
("buf5:", string(buf5)) //今天

 

 type PipeWriter struct {
	 contains filtered or unexported fields
	 }
 该类型就是上面那个pipe函数返回的类型,和下面这个类型是相对应的,因此有些例子可以放在一起理解
 type PipeReader struct {
 	// contains filtered or unexported fields
 }
	r1, w1 := ()
	go func() {
		([]byte("写入w1"))
		() //意味着这个pip不再写入
	}()
	buf6 := make([]byte, 6) //我只读取6个字节
	(buf6)
	() //读取六个之后我就封闭读取
	// n8, err := (buf6)
	// if err != nil {
	// 	(n8, err)
	// }
	// 0 io: read/write on closed pipe  这就是是在封闭之后在读取的结果,显示不能在一个封闭的pipe读取

 

type SectionReader struct {
		// contains filtered or unexported fields
	}
	// 包含read seek 和readat方法

	// func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
	// 创建一个sectionreader r是一个有readat方法的结构体,比如普通的 off代表从偏移量,从off的位置后开始读取,也就是
	// off不算,n表示读取几个字节,可以理解成一个容量
	// 下面是一段官网的代码
	// r := ("some  stream to be read\n")
	// s := (r, 5, 17)

	// if _, err := (, s); err != nil {
	// 	(err)
	// }
	// func (s *SectionReader) Read(p []byte) (n int, err error)
	// 很简单的读取方法,读取之后放在p缓存里面

	// func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
	// 很简单的偏移读取方法

	//func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
	// seek方法,更灵活的偏移读取方式

	//func (s *SectionReader) Size() int64
	// 返回这个sectionreader的字节大小,注意是原始的字节大小,不是未读取的部分的大小,那个一般是len

第三部分 interface

本章的接口多是一些定义,和接口相关的函数不多,我会举一些实现改接口的官方包里面的栗子

 ByteReader interface {
    ReadByte() (byte, error)
	}
 例:strings包里面的 func (r *Reader) ReadByte() (byte, error)

 ByteScanner interface {
	ByteReader
	UnreadByte() error
	 }
 注意这是一个接口的嵌套
 同样是strings包当中的func (r *Reader) UnreadByte() error,在下一读取的时候,返回最近一次读取的字节

 ByteWriter interface {
	WriteByte(c byte) error
	}
同样是strings包当中type Builder 当中的func (b *Builder) WriteByte(c byte) error,向builder缓存之中写入一个字节

 Closer interface {
	Close() error
	 }
 暂时没找到例子,不过上面的pip函数当中有个close方法,应该就是实现的这个功能

5. type WriterTo interface {
 WriteTo(w Writer) (n int64, err error)
	}
strings包当中的func (r *Reader) WriteTo(w ) (n int64, err error)函数,将未读取的内容打印出来

type ReadCloser interface {
	Reader
	Closer
	}
新的interface,很明显符合这个接口的reader有read和close方法,当然不会要你去写一个close函数
这个接口提供了这个函数,func NopCloser(r Reader) ReadCloser,你有reader就给你创建一个closer

type Reader interface {
    Read(p []byte) (n int, err error)
	 }
最基础的接口的了,比如说我们这个strings包当中的read方法,被读取的部分会存放在这个p缓存之中

// func LimitReader(r Reader, n int64) Reader 这个接口下面有这样一个很特殊的方法,因为其返回值竟然是一个Reader,尝试一下
reader9 := ("哈哈哈,笑死个人")
(, (reader9, 12))
// 就是一个将reader进行slice的方法

// func MultiReader(readers ...Reader) Reader
//既然有slice就有concat,该函数会将众多的reader整合成一个reader,例子我就不写了

func TeeReader(r Reader, w Writer) Reader,从reader当中读取的全部内容都会释放到writer之中,不会有中间的buffer
reader10 := ("什么情况,大清怎么亡了\n")
reader11 := (reader10, ) //重点要看一下这个返回的reader是什么
buf7 := make([]byte, 34)
(buf7)
(string(buf7)) //什么情况,大清怎么亡了,这个方法当中返回的reader11就是reader10本身,感觉是出错的时候拿来对比的

type ReaderAt interface {
	ReadAt(p []byte, off int64) (n int, err error)
	 }
 参考strings包,reader struct的readAt方法,在我发过的文章里有,那个方法就是实现的这个借口

type ReaderFrom interface {
		ReadFrom(r Reader) (n int64, err error)
	 }
这个接口是包含了一个ReadFrom函数,这个函数和read差不多,也是个读取,但是有个问题,这个函数读取之后似乎没有赋值给什么缓存

type RuneReader interface {
	ReadRune() (r rune, size int, err error)
}
看一下strings包的readRune函数,每次读取一个rune,三个返回值,r是读取的rune,err是错误处理,size是这个rune反映在字节上的大小,比如中文每个字就是3

type RuneScanner interface {
	RuneReader
	UnreadRune() error
}
跟上面相比,多了一个unreadrune函数,还是那句话,看看我写的strings包

type Seeker interface {
	Seek(offset int64, whence int) (int64, error)
 }
详见我写的strings包里的type reader当中的seek方法

type StringWriter interface {
	WriteString(s string) (n int, err error)
 }
//该接口可以参考 strings包中type Builder的writeString方法

type WriteCloser interface {
	Writer
	Closer
	}
混合接口,包含write和close方法

type WriteSeeker interface {
	 Writer
	Seeker
	 }
包含write和seek两个方法的接口

type Writer interface {
	Write(p []byte) (n int, err error)
	}
 参见strings官方包 type builder的write方法

 func MultiWriter(writers ...Writer) Writer
	r3 := ("some  stream to be read\n")

	var buf11, buf12 
	w3 := (&buf11, &buf12)

	if _, err := (w3, r3); err != nil {
		(err)
	}

	(())
	(())
贴一个官网上的写法,这个MultiWriter会将多个writer整合成一个(实际上不算整合,算一个统一操作),当你在w3进行操作的时候,实际上 也是同时对buf11和buf12进行操作,对于操作多个writer是个很好的写法

type WriterAt interface {
	WriteAt(p []byte, off int64) (n int, err error)
	}
readat函数的write版本,会从off的位置开始write

type WriterTo interface {
	WriteTo(w Writer) (n int64, err error)
	}
参见 strings包type Reader中的 writeto方法

该包其实是第一部分,io包还包含ioutil和fs,当然这是后续的内容,此外该包的interface部分都可以通过strings包当中的函数进行理解