io包是Golang标准库中的基础核心包 io包是Golang标准库中的基础核心包

io / bufio

主要内容: - io包 - bufio包 - 面向接口编程 - 其它

1. io包

io包是Golang标准库中的基础核心包

1.1 io包有多核心?

1
2
3
4
5
builder := new(strings.Builder)

reader := strings.NewReader("")

buffer := bytes.NewBuffer([]byte{})

1.2 io包目录结构

  • └─io
    • │ io.go
    • │ multi.go
    • │ pipe.go
    • └─ioutil
      • │ ioutil.go
      • │ tempfile.go

最主要的自然是io.go

1.3 io基本的接口

  • type Reader interface{ Read(p []byte) (n int, err error) }
  • type Writer interface{ Write(p []byte) (n int, err error) }
  • type Closer interface { Close() error }
  • type Seeker interface { Seek(offset int64, whence int) (int64, error) }
  • type WriterAt interface { WriteAt(p []byte, off int64) (n int, err error) }
  • type ByteWriter interface { WriteByte(c byte) error }
  • type ReaderAt interface { ReadAt(p []byte, off int64) (n int, err error) }
  • type ByteReader interface { ReadByte() (byte, error) }
  • type RuneReader interface { ReadRune() (r rune, size int, err error) }


1.4. 扩展接口

扩展接口又叫接口的组合

  • ReadWriter
  • ReadCloser
  • WriteCloser
  • ReadWriteCloser
  • ReadSeeker
  • WriteSeeker
  • ReadWriteSeeker
  • type ReaderFrom interface { ReadFrom(r Reader) (n int64, err error) }
  • type WriterTo interface { WriteTo(w Writer) (n int64, err error) }
  • type ByteScanner interface {
    ByteReader
    UnreadByte() error }
  • type RuneScanner interface {
    RuneReader
    UnreadRune() error }


1.5 io接口自身实现类型

  • *io.LimitedReader
  • *io.SectionReader
  • *io.teeReader 这是包级私有结构体
  • *io.multiReader 也是包级私有 , 多个读取器对象
  • *io.pipe 包级私有的数据类型实现io.Writer和io.Reader接口

1.5.1 代码示例-code

  • code目录


1.6 io包的方法

  • func ReadAtLeast(r Reader, buf []byte, min int) (n int, err error)
  • func ReadFull(r Reader, buf []byte) (n int, 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 Copy(dst Writer, src Reader) (written int64, err error) > 02示例1

2. 面向接口编程

语言印象: java面向对象编程,多态、范型 python是一门动态语言,灵活,简单 Golang面向接口是语言一大特点

2.1 duck类型

When I see a bird that walks like a duck and
swims like a duck and quacks like a duck,
I call that bird a duck.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
def greeting(a):
    return a.sayHello()

class Duck(object):
    def sayHello(self):
        print('ga ga ga!')
 
class Person(object):
    def sayHello(self):
        print('Hello!')
 
class Unknown(object):
    pass
 
duck = Duck()
person = Person()
u = Unknown()
u.sayHello = duck.sayHello

greeting(duck)
greeting(person)
greeting(u)  # 最后的输出为 'ga ga ga! Hello! ga ga ga!'

2.1. 源码中实现的接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
# 接口实现
git grep '^[^//].*\sRead(.*byte).*int.*error)' -- *[^_test].go | wc -l
git grep '^[^//].*\sWrite(.*byte).*int.*error)' -- *[^_test].go | wc -l
git grep '^[^//].*\sClose().*error)' -- *[^_test].go | wc -l
git grep '^[^//].*\sSeek(.*int64,.*int).*int64.*error)' -- *[^_test].go | wc -l

# 方法调用
git grep '^[^//].*\.Read([^,]*)' -- *[^_test].go | wc -l
git grep '^[^//].*\.Write([^,]*)' -- *[^_test].go | wc -l
git grep '^[^//].*\.Close()' -- *[^_test].go | wc -l
git grep '^[^//].*\.Seek(.*,.*)' -- *[^_test].go | wc -l
git grep '^[^//].*ReadWriter.*'
git grep '^[^//].*ReadCloser.*'
git grep '^[^//].*WriteCloser.*'
git grep '^[^//].*ReadWriteCloser.*'
git grep '^[^//].*ReadSeeker.*'
git grep '^[^//].*WriteSeeker.*'
git grep '^[^//].*ReadWriteSeeker.*'

# pipe
git grep 'func.*\sPipe().*'
git grep '^[^//].*io.Pipe(.*,.*)'


2.2. 其他典型应用

  • Error()类型
  • database/sql
  • 一个未知结构的json如何转化为Go的数据结构?

3. bufio

  • bufio数据类型
    Reader
    Scanner
    Writer和ReaderWriter


3.1 Reader

1
2
3
4
5
6
7
8
type Reader struct {
	buf          []byte
	rd           io.Reader // reader provided by the client 用户提供的reader
	r, w         int       // buf read and write positions 读和写的位置
	err          error
	lastByte     int
	lastRuneSize int
}


3.1.1 Reader方法

  • func NewReaderSize(rd io.Reader, size int) *Reader
  • func NewReader(rd io.Reader) *Reader
  • func (b *Reader) Peek(n int) ([]byte, error)
  • func (b *Reader) ReadSlice(delim byte) (line []byte, err error)
  • func (b *Reader) ReadByte() (byte, error)
  • func (b *Reader) fill()

3.2 Writer

1
2
3
4
5
6
type Writer struct {
	err error
	buf []byte
	n   int
	wr  io.Writer
}


3.2.1 Writer方法

  • func (b *Writer) Flush() error
  • func (b *Writer) WriteString(s string) (int, error)
  • func (b *Writer) WriteRune(r rune) (size int, err error)
  • func (b *Writer) WriteRune(r rune) (size int, err error)

  • bufio示例

  • getHanzi项目

4 其它

4.1. 其它1 2014年pkg\src合并到src目录后的提交次数统计

文件 提交次数
io.go 26
multi.go 10
pipe.go 10
ioutil.go 5


4.2. 其它2

4.2.1 bufio ReadLine方法描述中有一句ReadLine is a low-level line-reading primitive,这句中的primitive英文翻译为原语。如何理解?

4.2.2 bufio ReadBytes方法描述中表示如果发生错误,返回发生错误之前读取的数据和发生的错误,之前有些语言习惯发生错误时,并不返回数据,包括我的习惯。 所以有些逻辑不判断错误,而是判断返回的数据来判断方法,后来发现这个在Go语言中并不是通用。

4.2.3 bufio 只有三个接口体ReaderWriterReadWriter,包括前面的io包,里面的io也是相关的几个接口,dave.cheney 说的Golang Single Responsibility Principle

设计原则:Gopher Dave Cheney博客,博客中谈及Golang设计

Single Responsibility Principle