golang标准库-io

io包提供了对I/O操作的基本接口。本包的基本任务是包装这些操作已有的实现,使之成为共享的公共接口,因为这些接口对底层实现包装,除非得到其它方面的通知,客户端不应假设它们是并发执行安全的。
这个包在日常的开发中可能用的不多,本章主要对包的接口做说明,可以做的代码示例不多,具体的代码实例就用文件的I/O来举例,网络IO不好模拟。不过都是IO,原理上来说都是一样的

这个包定义了很多的IO接口,每个接口都有特定的方法,但这些接口本包都不提供实现,因为这个包是提供对操作系统底层IO的封装,包里面的基本所有接口都有其它标准库实现,比如os包的File结构体就实现了本包的IO接口,还有 http包也实现了本包的IO接口;所以这个包大多数都是 抽象接口,具体的可用方法只有几个,我们先来看几个基础方法,再看包里面的接口。

不过在认识本包的几个方法之前,我们先看三个IO层最基础的接口,(go编程中,所有可以操作IO的结构体基本都实现了以下三个方法)对包有一个大概的了解:

// Reader接口,有一个Read方法,Writer接口有一个Write方法,Closer接口有一个Close,这是标准的读写关闭接口,实现了这些方法的结构体(例如os包的File结构体)
type Reader interface {
    Read(p []byte) (n int, err error)
}
// Writer接口用于包装基本的写入方法。,os包File结构体也实现了这个接口
type Writer interface {
    Write(p []byte) (n int, err error)
}
// Closer接口是标准的关闭IO流的接口,基本所有实现了IO接口的结构体这个接口也是实现了的
type Closer interface {
    Close() error
}

下面我们来看os包的几个可用方法:

func TeeReader(r Reader, w Writer) Reader => 这个方法接受一个可读流和一个可写流,返回一个可读的流,然后只要从返回的可读流中读取的数据,都会自动写入到传入可写流w里面,不好理解看下面的例子:
func main() {

	wd,_ := os.Getwd() // 获取工作路径

	fileRead,_ := os.Open(wd+"/src/read.txt") // 打开一个文件(这个文件事先创建好了,并写有一行hello world)
	fileWrite,_ := os.Create(wd+"/src/write.txt") // 创建并打开一个可写的文件(这个文件不存在,我们通过代码把它创建出来)

	read := io.TeeReader(fileRead,fileWrite) // 创建一个读取的reader
	b := make([]byte,1024) // 创建一个byte切片保存数据
	read.Read(b) // 从可读的流中读取内容
    // 上面Read方法执行,实际是从fileRead中读取数据,然后又将数据写入到了fileWrite中,结果就是,write.txt文件中写入了read.txt中的数据

}
func MultiReader(readers ...Reader) Reader => 这个方法接受一个或多个可读流,将这些可读流合并起来,返回一个总的新的可读流,读取返回的可读流实际是依次读取传入的可读流,当传入的所有的可读流都没有可读数据时候,才返回EOF

golang标准库-io_第1张图片 

func MultiWriter(writers ...Writer) Writer => 这个方法接受多个可写流,返回一个总的可写流,当想总的可写流中写入数据时,将向传入的所有可写流写入数据

 golang标准库-io_第2张图片

  

func Copy(dst Writer, src Reader) (written int64, err error) => 将src中数据拷贝到dst中,返回拷贝的字节数

 

func main() {

	wd,_ := os.Getwd() // 获取工作路径

	fileRead,_ := os.Open(wd+"/src/read.txt") // 打开一个文件(文件里面有一行hello world)
	fileWrite,_ := os.OpenFile(wd+"/src/write.txt",os.O_WRONLY, 777) // 打开一个可写的文件,第二个参数打开文件的模式,这里为只写;最后一个参数为文件的权限

	io.Copy(fileWrite,fileRead) // 将read.txt的内容拷贝到write中
	// f执行完成后,查看write.txt可以看到,成功将read.txt中的内容拷贝了过来

}
func CopyN(dst Writer, src Reader, n int64) (written int64, err error) => 将src中n个字节的数据拷贝到dst中,只有当err为nil时,返回的written才会等于n,跟Copy不同的是,后者可以指定拷贝数据的大小。不再演示
func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error) => 从r至少读取min字节数据填充进buf。函数返回写入的字节数和错误(如果没有读取足够的字节)。
只有没有读取到字节时才可能返回EOF;如果读取了有但不够的字节时遇到了EOF,函数会返回ErrUnexpectedEOF。 如果min比buf的长度还大,函数会返回ErrShortBuffer。只有返回值err为nil时,返回值n才会不小于min。
func ReadFull(r Reader, buf []byte) (n int, err error) => 从r中读取len(buf)字节数据填充进buf。
函数返回写入的字节数和错误(如果没有读取足够的字节)。只有没有读取到字节时才可能返回EOF;如果读取了有但不够的字节时遇到了EOF,函数会返回ErrUnexpectedEOF。 只有返回值err为nil时,返回值n才会等于len(buf)。
func WriteString(w Writer, s string) (n int, err error) => 将字符串s的内容写入w中。如果w已经实现了WriteString方法,函数会直接调用该方法。

至此,io包的可用方法就算介绍完了,都是几个对读写的操作方法。开发中用的也不算不多,但也有用到的地方(个人认为)。

下面我们了解一些io包的其它接口

前面已经介绍了Reader,Writer,Closer接口。

type Seeker interface {
    Seek(offset int64, whence int) (int64, error)
}
// Seeker接口用于包装基本的移位方法。
type ReadCloser interface {
    Reader
    Closer
}
// ReadCloser接口聚合了基本的读取和关闭操作。
type WriteCloser interface {
    Writer
    Closer
}
// WriteCloser接口聚合了基本的写入和关闭操作。

 

type WriteSeeker interface {
    Writer
    Seeker
}
// WriteSeeker接口聚合了基本的写入和移位操作。
type ReadWriter interface {
    Reader
    Writer
}
// ReadWriter接口聚合了基本的读写操作。

 

type ReadWriteCloser interface {
    Reader
    Writer
    Closer
}
// ReadWriteCloser接口聚合了基本的读写和关闭操作。

 

type ReadWriteSeeker interface {
    Reader
    Writer
    Seeker
}
// ReadWriteSeeker接口聚合了基本的读写和移位操作。

 

type ReaderAt interface {
    ReadAt(p []byte, off int64) (n int, err error)
}
// ReaderAt接口包装了基本的ReadAt方法。

 

type WriterAt interface {
    WriteAt(p []byte, off int64) (n int, err error)
}
// WriterAt接口包装了基本的WriteAt方法。

以上已经包含了io包的80%的接口,全做了解,前面已经说明,这些接口都是在其它包提供实现的,io包只是提供定义,还有几个接口就不放上来了,因为也都是上面的接口各种变种,用到的时候再去查看吧,文章篇幅已经太长了,这些也全做了解,不过几个基本的接口还是要知道,比如Reader和Writer以及Closer接口,这三个接口是IO层最基础的接口

文档地址:https://studygolang.com/pkgdoc

你可能感兴趣的:(go,golang标准库)