返回

图像处理利器 - bufio读取原理

后端

图文解读 BufferedReader

为了深入探讨bufio包的读取原理,我们从BufferedReader说起。它是一种常用的IO流,利用缓冲机制,以较高的效率读取数据,它实现了三个接口:Reader、ReadSeeker、Seeker。

BufferedReader 的优化策略

BufferedReader采用了多种策略优化数据读取过程,包括:

利用缓冲区 :缓冲区,存储从流中读取的数据,降低频繁访问IO设备的次数,减少因磁盘寻址而产生的延迟。

预读 :预读,提前读取一些数据存放在缓冲区中,避免每次读取数据时进行磁盘寻址。

跳读 :跳读,根据缓冲区的起始位置和当前位置,直接读取剩余的数据,无需再次从头读取。

ReadAtLeast方法

ReadAtLeast方法用于读取至少指定数量的数据,如果没有足够的数据可读,它将阻塞直到满足要求。它的签名如下:

func (r *Reader) ReadAtLeast(b []byte, min int) (n int, err error)

返回多条记录

使用BufferedReader读取多条记录,我们可以使用以下代码:

func ReadLines(r *bufio.Reader) ([]string, error) {
    var lines []string
    for {
        line, err := r.ReadString('\n')
        if err != nil {
            if err != io.EOF {
                return nil, err
            }
            break
        }
        lines = append(lines, strings.TrimSpace(line))
    }
    return lines, nil
}

withRange方法

bufio.NewReaderSize(r io.Reader, size int)

我们可以使用withRange方法来创建带指定缓冲区的BufferedReader:

func WithRange(r io.Reader, min, max int) *Reader

pipeline demo

package main

import (
	"bufio"
	"fmt"
	"io"
	"log"
	"net"
)

func handleConn(c net.Conn) {
	defer c.Close()
	r := bufio.NewReader(c)
	for {
		msg, err := r.ReadString('\n')
		if err != nil {
			if err == io.EOF {
				log.Println("client closed")
			} else {
				log.Println("read error:", err)
			}
			return
		}
		fmt.Println("received:", msg)
	}
}

func main() {
	l, err := net.Listen("tcp", ":8080")
	if err != nil {
		log.Fatal(err)
	}
	defer l.Close()
	for {
		c, err := l.Accept()
		if err != nil {
			log.Println("accept error:", err)
			continue
		}
		go handleConn(c)
	}
}

以上是硬核,图解bufio包系列之读取原理这篇文章的主体内容。