今日长缨在手,何日缚住苍龙
五一假期的这几天,闲来无事,于是找了之前关系较好的二位同学聊了聊各自的现状,暂且称呼这两位同学分别为A和B吧,A同学本科学的也是计算机,因为学校地理位置的因素,大四实习的时候A同学和我们寝室的其他几个人都不约而同的选择了北京这座城市,然而毕业的时候A同学因为女朋友的原因选择前去济南工作,他们两个人从高中毕业开始确立关系,后来又熬过了大学四年的异地恋,毕业后几年的时间过去了,一度曾经以为两个人能最终修成正果,结果闲聊中得知两人早在几个月之前就已经分道扬镳,霎时间竟不知如何安慰A同学,分手之后A同学毅然决然的离开了伤心地济南,更换了手机号码,选择回家继承家业,算是彻底与这个行业诀别了,通过聊天得知,虽然离开了这个行业,但是目前的薪资大概是日薪几万元,没有休息日-一天的收入超过过去一年的收入,于是调侃到等到混不下去了给他打工去。至于B同学,本科的时候也是学的计算机,前三年一直在参加ACM相关的比赛,等到大四的时候也没有出去找实习,一门心思的将精力放在考研上,结果那年不知什么原因,发挥时常,没有成功上岸,由于校招的时间已经错过,在加上又没有什么工作的经验导致找工作的时候一度碰壁,万念俱灰之下在北京随便找了个5k薪资的公司上班,但据B同学收说,公司工资虽然低,不过好在日常的工作基本上处于摸鱼的阶段。在这家公司攒够一年的工作之后,B同学毅然决然的转变了工作的方向,到新公司一年不到的时间薪资翻了好几倍,截止到目前为止薪资待遇大概接近50w,不得不说选对方向确实很重要。
go语言的io包
go语言的io包主要提供了一些操作io流的函数和方法,下面将针对这些函数和方法展开讲解。
package main
/*********************************************************************/
/**************** golang中io包相关API讲解 **************************/
/*******************************************************************/
/*
Constants
Variables
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)
func Pipe() (*PipeReader, *PipeWriter)
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)
func WriteString(w Writer, s string) (n int, err error)
type ByteReader
type ByteScanner
type ByteWriter
type Closer
type LimitedReader
func (l *LimitedReader) Read(p []byte) (n int, err error)
type PipeReader
func (r *PipeReader) Close() error
func (r *PipeReader) CloseWithError(err error) error
func (r *PipeReader) Read(data []byte) (n int, err error)
type PipeWriter
func (w *PipeWriter) Close() error
func (w *PipeWriter) CloseWithError(err error) error
func (w *PipeWriter) Write(data []byte) (n int, err error)
type ReadCloser
func NopCloser(r Reader) ReadCloser
type ReadSeekCloser
type ReadSeeker
type ReadWriteCloser
type ReadWriteSeeker
type ReadWriter
type Reader
func LimitReader(r Reader, n int64) Reader
func MultiReader(readers ...Reader) Reader
func TeeReader(r Reader, w Writer) Reader
type ReaderAt
type ReaderFrom
type RuneReader
type RuneScanner
type SectionReader
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
type Seeker
type StringWriter
type WriteCloser
type WriteSeeker
type Writer
func MultiWriter(writers ...Writer) Writer
type WriterAt
type WriterTo
*/
func main() {
/**
*将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
*对成功的调用,返回值err为nil而非EOF,因为Copy定义为从src读取直到EOF,它不会将读取到EOF
*视为应报告的错误。如果src实现了WriterTo接口,本函数会调用src.WriteTo(dst)进行拷贝;
*否则如果dst实现了ReaderFrom接口,本函数会调用dst.ReadFrom(src)进行拷贝。
*func Copy(dst Writer, src Reader) (written int64, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
*/
/**
*CopyBuffer与Copy相同,区别在于CopyBuffer逐步遍历提供的缓冲区(如果需要),而不是分配临时缓冲区。
*如果buf为nil,则分配一个;否则,为0。否则,如果长度为零,则CopyBuffer会发生混乱。
*如果src实现WriterTo或dst实现ReaderFrom,则buf将不用于执行复制。
*func CopyBuffer(dst Writer, src Reader, buf []byte) (written int64, err error)
*/
/*
r1 := strings.NewReader("first reader\n")
r2 := strings.NewReader("second reader\n")
buf := make([]byte, 8)
if _, err := io.CopyBuffer(os.Stdout, r1, buf); err != nil {
log.Fatal(err)
}
if _, err := io.CopyBuffer(os.Stdout, r2, buf); err != nil {
log.Fatal(err)
}
*/
/**
*CopyN将n个字节(或直到出错)从src复制到dst。它返回复制的字节数以及复制时遇到的最早错误。
*返回时,仅当err == nil时才写== n。如果dst实现了ReaderFrom接口,则使用该接口实现副本。
*func CopyN(dst Writer, src Reader, n int64) (written int64, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read")
if _, err := io.CopyN(os.Stdout, r, 4); err != nil {
log.Fatal(err)
}
*/
/**
*管道创建一个同步的in-memory管道。它可以用来连接期望io.Reader的代码和期望io.Writer的代码。
*管道上的读取和写入是一对一匹配的,除非需要多个读取来消耗单个写入。也就是说,每次对PipeWriter
*的写入都将阻塞,直到它满足从PipeReader读取的一个或多个读取,这些读取会完全消耗写入的数据。
*数据直接从写入复制到相应的一个或多个读取;没有内部缓冲。可以并行或以关闭方式
*并行调用读取和写入是安全的。
*并行调用Read和并行调用Write也是安全的:单个调用将按顺序进行门控。
*func Pipe() (*PipeReader, *PipeWriter)
*/
/*
r, w := io.Pipe()
go func() {
fmt.Fprint(w, "some io.Reader stream to be read\n")
w.Close()
}()
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
*/
/**
*ReadAll从r读取直到出现错误或EOF,然后返回读取的数据。成功调用将返回err == nil,而不是err == EOF。
*因为ReadAll被定义为从src读取直到EOF,所以它不会将读取的EOF视为要报告的错误。
*func ReadAll(r Reader) ([]byte, error)
*/
/*
r := strings.NewReader("Go is a general-purpose language designed with systems programming in mind.")
b, err := io.ReadAll(r)
if err != nil {
log.Fatal(err)
}
fmt.Printf("%s", b)
*/
/**
*ReadAtLeast从r读取到buf,直到它至少读取了最小字节。它返回复制的字节数,
*如果读取的字节数少则返回错误。仅当未读取任何字节时,
*错误才是EOF。如果在读取少于最小字节后发生EOF,则ReadAtLeast返回ErrUnexpectedEOF。
*如果min大于buf的长度,则ReadAtLeast
*返回ErrShortBuffer。返回时,当且仅当err == nil时,n> = min。
*如果r返回至少读取了最小字节的错误,则丢弃该错误。
*func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 14)
if _, err := io.ReadAtLeast(r, buf, 4); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
shortBuf := make([]byte, 3)
if _, err := io.ReadAtLeast(r, shortBuf, 4); err != nil {
fmt.Println("error:", err)
}
longBuf := make([]byte, 64)
if _, err := io.ReadAtLeast(r, longBuf, 64); err != nil {
fmt.Println("error:", err)
}
*/
/**
*ReadFull从r精确读取len(buf)个字节到buf。它返回复制的字节数,如果读取的字节数少则返回错误。
*仅当未读取任何字节时,错误才是EOF。如果在读取了一些但不是全部字节后发生EOF,则ReadFull返回
*ErrUnexpectedEOF。返回时,当且仅当err == nil时,n == len(buf)。如果r返回读取至少len(buf)
*个字节的错误,则该错误将被丢弃。
*func ReadFull(r Reader, buf []byte) (n int, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
buf := make([]byte, 4)
if _, err := io.ReadFull(r, buf); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
longBuf := make([]byte, 64)
if _, err := io.ReadFull(r, longBuf); err != nil {
fmt.Println("error:", err)
}
*/
/**
*ReadFull从r精确读取len(buf)个字节到buf。它返回复制的字节数,如果读取的字节数少则返回错误。
*func WriteString(w Writer, s string) (n int, err error)
*/
/*
io.WriteString(os.Stdout, "Hello World")
*/
/*********************************************************************/
/**************** golang中io包LimitedReader结构体API讲解 **********/
/********************************************************************/
/**
*LimitReader返回一个从r读取但在n字节后以EOF停止的Reader。基础实现是* LimitedReader。
*func (l *LimitedReader) Read(p []byte) (n int, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
lr := io.LimitReader(r, 4)
if _, err := io.Copy(os.Stdout, lr); err != nil {
log.Fatal(err)
}
*/
/*********************************************************************/
/**************** golang中io包PipeReader结构体API讲解 *************/
/********************************************************************/
/**
*Close关闭读取器;关闭后如果对管道的写入端进行写入操作,就会返回(0, ErrClosedPip)。
*func (r *PipeReader) Close() error
*/
/**
*CloseWithError类似Close方法,但将调用Write时返回的错误改为err。
*func (r *PipeReader) CloseWithError(err error) error
*/
/**
*Read实现了标准Reader接口:它从管道中读取数据,会阻塞直到写入端开始写入或写入端被关闭。
*func (r *PipeReader) Read(data []byte) (n int, err error)
*/
/*
pipeReader, pipeWriter:= io.Pipe()
go func() {
pipeWriter.Write([]byte("GfG"))
pipeWriter.Write([]byte("GeeksforGeeks"))
pipeWriter.Write([]byte("GfG is a CS-Portal."))
pipeWriter.Close()
pipeWriter.Write([]byte("Author!"))
}()
data:= make([]byte, 20)
for i:= 0; i < 3; i++ {
n, err:= pipeReader.Read(data)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", data[:n])
fmt.Printf("%v\n", n)
}
*/
/*********************************************************************/
/**************** golang中io包PipeWriter结构体API讲解 **************/
/********************************************************************/
/**
*Close关闭写入器;关闭后如果对管道的读取端进行读取操作,就会返回(0, EOF)。
*func (w *PipeWriter) Close() error
*/
/*
pipeReader, pipeWriter:= io.Pipe()
go func() {
pipeWriter.Write([]byte("GfG"))
pipeWriter.Write([]byte("GeeksforGeeks"))
pipeWriter.Close()
pipeWriter.Write([]byte("GfG is a CS-Portal."))
}()
buffer:= make([]byte, 50)
for i:= 0; i < 4; i++ {
n, err:= pipeReader.Read(buffer)
if err != nil {
panic(err)
}
fmt.Printf("%s\n", buffer[:n])
}
*/
/**
*CloseWithError类似Close方法,但将调用Read时返回的错误改为err。
*func (w *PipeWriter) CloseWithError(err error) error
*/
/*
pipeReader, pipeWriter:= io.Pipe()
data:= make([]byte, 20)
go func() {
pipeReader.Read(data)
pipeReader.CloseWithError(fmt.Errorf("There is an "+ "error in the code written!"))
}()
for i:= 0; i < 1; i++ {
n, err:= pipeWriter.Write([]byte("GeeksforGeeks!"))
if err != nil {
panic(err)
}
fmt.Printf("%v\n", string(data))
fmt.Printf("%v\n", n)
}
*/
/**
*Write实现了标准Writer接口:它将数据写入到管道中,会阻塞直到读取器读完所有的数据或读取端被关闭。
*func (w *PipeWriter) Write(data []byte) (n int, err error)
*/
/*
pipeReader, pipeWriter:= io.Pipe()
data:= make([]byte, 20)
go func() {
pipeReader.Read(data)
pipeReader.Close()
}()
for i:= 0; i < 1; i++ {
n, err:= pipeWriter.Write([]byte("GfG!"))
if err != nil {
panic(err)
}
fmt.Printf("%v\n", string(data))
fmt.Printf("%v\n", n)
}
*/
/*********************************************************************/
/**************** golang中io包 ReadCloser结构体API讲解 ************/
/*******************************************************************/
/**
*NopCloser返回带有无操作Close方法的ReadCloser,该方法包装提供的Reader r。
*func NopCloser(r Reader) ReadCloser
*/
/*
r := strings.NewReader("hello world")
read := io.NopCloser(r)
fmt.Println(read)
*/
/*********************************************************************/
/**************** golang中io包Reader结构体API讲解 *****************/
/*******************************************************************/
/**
*返回一个Reader,它从r中读取n个字节后以EOF停止。返回值接口的底层为*LimitedReader类型。
*func LimitReader(r Reader, n int64) Reader
*/
/*
r:= strings.NewReader("Geeks\n")
res:= io.LimitReader(r, 3)
op, err:= io.Copy(os.Stdout, res)
if err != nil {
panic(err)
}
fmt.Printf("\nn:%v\n", op)
*/
/**
*MultiReader返回一个将提供的Reader在逻辑上串联起来的Reader接口。他们依次被读取。
*当所有的输入流都读取完毕,Read才会返回EOF。如果readers中任一个返回了非nil非EOF的错误,
*Read方法会返回该错误。
*func MultiReader(readers ...Reader) Reader
*/
/*
r1 := strings.NewReader("first reader ")
r2 := strings.NewReader("second reader ")
r3 := strings.NewReader("third reader\n")
r := io.MultiReader(r1, r2, r3)
if _, err := io.Copy(os.Stdout, r); err != nil {
log.Fatal(err)
}
*/
/**
*TeeReader返回一个将其从r读取的数据写入w的Reader接口。所有通过该接口对r的读取
*都会执行对应的对w的写入。
*没有内部的缓冲:写入必须在读取完成前完成。写入时遇到的任何错误都会作为读取错误返回。
*func TeeReader(r Reader, w Writer) Reader
*/
/*
var r io.Reader = strings.NewReader("some io.Reader stream to be read\n")
r = io.TeeReader(r, os.Stdout)
io.ReadAll(r)
*/
/*********************************************************************/
/**************** golang中io包SectionReader结构体API讲解 **********/
/********************************************************************/
/**
*返回一个从r中的偏移量off处为起始,读取n个字节后以EOF停止的SectionReader。
*func NewSectionReader(r ReaderAt, off int64, n int64) *SectionReader
*/
/*
reader:= strings.NewReader("Geeks\n")
r:= io.NewSectionReader(reader, 3, 5)
Reader, err:= io.Copy(os.Stdout, r)
if err != nil {
panic(err)
}
fmt.Printf("n:%v\n", Reader)
*/
/**
*
*func (s *SectionReader) Read(p []byte) (n int, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
if _, err := io.Copy(os.Stdout, s); err != nil {
log.Fatal(err)
}
*/
/**
*
*func (s *SectionReader) ReadAt(p []byte, off int64) (n int, err error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
buf := make([]byte, 6)
if _, err := s.ReadAt(buf, 10); err != nil {
log.Fatal(err)
}
fmt.Printf("%s\n", buf)
*/
/**
*
*func (s *SectionReader) Seek(offset int64, whence int) (int64, error)
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
s := io.NewSectionReader(r, 5, 17)
if _, err := s.Seek(10, io.SeekStart); err != nil {
log.Fatal(err)
}
if _, err := io.Copy(os.Stdout, s); err != nil {
log.Fatal(err)
}
*/
/**
*Size返回该片段的字节数。
*func (s *SectionReader) Size() int64
*/
/*
reader:= strings.NewReader("Geeks")
r:= io.NewSectionReader(reader, 1, 4)
size:= r.Size()
fmt.Printf("The size of the section in bytes is:%v\n", size)
*/
/*********************************************************************/
/**************** golang中io包Writer结构体API讲解 ******************/
/*******************************************************************/
/**
*MultiWriter创建一个Writer接口,会将提供给其的数据写入所有创建时提供的Writer接口。
*func MultiWriter(writers ...Writer) Writer
*/
/*
r := strings.NewReader("some io.Reader stream to be read\n")
var buf1, buf2 bytes.Buffer
w := io.MultiWriter(&buf1, &buf2)
if _, err := io.Copy(w, r); err != nil {
log.Fatal(err)
}
fmt.Print(buf1.String())
fmt.Print(buf2.String())
*/
}
小结
io包在平时的开发过程中运用的频率还是非常高的,从这一点上来讲这个包的相关知识点也是需要掌握的,如果还没有掌握的最好还是加强练习下。