Go语言学习笔记—golang标准库io包


前言

Go语言中,为了方便开发者使用,将IO操作封装在了如下几个包中:

  • io为IO原语(I/O primitives)提供基本的接口
  • io/ioutil封装一些实用的I/O函数
  • fmt实现格式化I/O
  • bufio实现带缓冲I/O

其中io包中提供I/O原始操作的一系列接口。它主要包装了一些已有的实现,如 os 包中的那些,并将这些抽象成为实用性的功能和一些其他相关的接口。

一 错误变量

  • var EOF = errors.New(“EOF”)
    正常输入结束Read返回EOF,如果在一个结构化数据流中EOF在不期望的位置出现了,则应返回错误ErrUnexpectedEOF或者其它给出更多细节的错误。

  • var ErrClosedPipe = errors.New(“io: read/write on closed pipe”)
    当从一个已关闭的Pipe读取或者写入时,会返回ErrClosedPipe。

  • var ErrNoProgress = errors.New(“multiple Read calls return no data or error”)
    某些使用io.Reader接口的客户端如果多次调用Read都不返回数据也不返回错误时,就会返回本错误,一般来说是io.Reader的实现有问题的标志。

  • var ErrShortBuffer = errors.New(“short buffer”)
    ErrShortBuffer表示读取操作需要大缓冲,但提供的缓冲不够大。

  • var ErrShortWrite = errors.New(“short write”)
    ErrShortWrite表示写入操作写入的数据比提供的少,却没有显式的返回错误。

  • var ErrUnexpectedEOF = errors.New(“unexpected EOF”)
    ErrUnexpectedEOF表示在读取一个固定尺寸的块或者数据结构时,在读取未完全时遇到了EOF。

二 基础接口

2.1 Reader接口

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

Read 将 len§ 个字节读取到 p 中。它返回读取的字节数 n(0 <= n <= len§)以及任何遇到的错误。即使 Read 返回的 n < len§,它也会在调用过程中使用 p的全部作为暂存空间。若一些数据可用但不到 len§ 个字节,Read 会照例返回可用的东西,而不是等待更多。

当 Read 在成功读取 n > 0 个字节后遇到一个错误或 EOF 情况,它就会返回读取的字节数。它会从相同的调用中返回(非nil的)错误或从随后的调用中返回错误(和 n == 0)。这种一般情况的一个例子就是 Reader 在输入流结束时会返回一个非零的字节数,可能的返回不是 err == EOF 就是 err == nil。无论如何,下一个 Read 都应当返回 0, EOF。

调用者应当总在考虑到错误 err 前处理 n > 0 的字节。这样做可以在读取一些字节,以及允许的 EOF 行为后正确地处理I/O错误。

Read 的实现会阻止返回零字节的计数和一个 nil 错误,调用者应将这种情况视作空操作。

实例演示:

package main

import (
	"fmt"
	"io"
	"os"
)

func main() {
   
	f, err := os.Open("a.txt")
	if err != nil {
   
		fmt.Printf("err: %v\n", err)
		return
	}
	defer f.Close()

	buf := make([]byte, 12) // 实例化一个长度为4的[]byte

	for {
   
		n, err2 := f.Read(buf) // 将内容读至buf
		if n == 0 || err2 == io.EOF {
   
			fmt.Println("文件以读取完毕")
			break
		}
		fmt.Println(string(buf[:n]))
	}

}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
 hello world
文件以读取完毕

[Done] exited with code=0 in 0.931 seconds

其中a.txt内容为:

 hello world

2.2 Writer接口

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

Write 将 len§ 个字节从 p 中写入到基本数据流中。它返回从 p 中被写入的字节数n(0 <= n <= len§)以及任何遇到的引起写入提前停止的错误。若 Write 返回的n < len§,它就必须返回一个非nil的错误。Write 不能修改此切片的数据,即便它是临时的。

实例演示:

package main

import (
	"os"
)

func main() {
   
	f, _ := os.OpenFile("a.txt", os.O_RDWR|os.O_APPEND, 0775) // 以读写模式打开文件,并且在写操作时将数据附加到文件尾部
	f.Write([]byte(" hello golang"))
	f.Close()
}

运行结果:

a.txt内容更新为:

 hello world hello golang

其中a.txt初始内容为:

 hello world

2.3 Seeker接口

type Seeker interface {
   
    Seek(offset int64, whence int) (int64, error)
}

Seeker 用来移动数据的读写指针

Seek 设置下一次读写操作的指针位置,每次的读写操作都是从指针位置开始的

  • whence 的含义:

    • 如果 whence 为 0:表示从数据的开头开始移动指针
    • 如果 whence 为 1:表示从数据的当前指针位置开始移动指针
    • 如果 whence 为 2:表示从数据的尾部开始移动指针
  • offset 是指针移动的偏移量

    返回移动后的指针位置和移动过程中遇到的任何错误

实例演示:

package main

import (
	"fmt"
	"os"
)

func main() {
   
	f, _ := os.Open("a.txt") // 打开文件后,光标默认在文件开头
	f.Seek(3, 0)             // 从索引值为3处开始读
	buf := make([]byte, 10)  // 设置缓冲区
	n, _ := f.Read(buf)      // 将内容读到缓冲区内
	fmt.Printf("n: %v\n", n)
	fmt.Printf("string(buf): %v\n", string(buf))
	f.Close()
}

运行结果:

[Running] go run "c:\Users\Mechrevo\Desktop\go_pro\test.go"
n: 9
string(buf): llo world
[Done] exited with code=0 in 1.526 seconds

其中a.txt内容为:

 hello world

2.4 Closer接口

type Closer interface {
   
	Close() error
}

Closer关闭的接口, 带有Close() 方法, 但是行为没有定义,所以 可以特定行为来实现
在整个标准库内都没有对Closer的引用,只有实现,用法都是开启某某连接/流,在用完/报错后在进行Close的操作。

三 组合接口

组合接口是对多个接口进行了组合,当同时实现多个接口时,可以使用组合接口进行传递

3.1 ReadWriter接口

type ReadWriter interface {
   
	Reader
	Writer
}

ReadWriter接口聚合了基本的读写操作。

3.2 ReadCloser接口

type ReadCloser interface {
   
	Reader
	Closer
}

ReadCloser就是Reader+Closer,例如在ioutil中的NopCloser方法返回的就是一个ReadCloser,但是里面的Close就是个空函数,毫无作用。

3.3 WriteCloser接口

type WriteCloser interface {
   
	Writer
	Closer
}

WriteCloser接口聚合了基本的写入和关闭操作。

3.4 ReadWriteCloser接口

type ReadWriteCloser interface {
   
	Reader
	Writer
	Closer
}

ReadWriteCloser接口聚合了基本的读写和关闭操作。

3.5 ReadSeeker接口

type ReadSeeker interface {
   
	Reader
	Seeker
}

ReadSeeker接口聚合了基本的读取和移位操作。

3.6 WriteSeeker接口

type WriteSeeker interface {
   
	Writer
	Seeker
}

WriteSeeker接口聚合了基本的写入和移位操作。

3.7 ReadWriteSeeker接口

type ReadWriteSeeker interface {
   
	Reader
	Writer
	Seeker
}

ReadWriteSeeker接口聚合了基本的读写和移位操作

四 指定读写器读写接口

4.1 ReaderFrom接口

type ReaderFrom interface {
   
	ReadFrom(r Reader) (n int64
  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值