golang bufio浅析

bufio 在读写文件时提供了缓存,先将要读取或写入的内容放到缓存中

read

func bufIoRead() {
    file := "./test-file"
    fd, err := os.Open(file)
    if err != nil {
        panic(err)
    }
    defer fd.Close()
    // 初始化一个缓冲区大小为100byte的对象
    b := bufio.NewReaderSize(fd, 100)
    ctx := make([]byte, 30)
    var buf bytes.Buffer
    fmt.Println("b size is: ", b.Size())
    // 将b中的缓存数据读入ctx中
    // 如果缓存不为空,则只能读出缓冲中的数据,不会从底层io.Reader中提取数据,如果缓存为空,则:
    // 1、len(ctx) >= 缓存大小,则跳过缓存,直接从底层io.Reader中读出到p中
    // 2、len(ctx)< 缓存大小,则先将数据从底层io.Reader中读取到缓存中,再从缓存读取到p中。
    // 从缓存中读取出的数据将不会再存在与缓存中
    if _, err := b.Read(ctx); err != nil {
        panic(err)
    }
    buf.Write(ctx)
    fmt.Println(buf.String())
    // b.Buffered()返回未被读取的缓存大小
    fmt.Println("剩余缓冲大小: ", b.Buffered())
    _, err = b.Read(ctx)
    if err != nil {
        panic(err)
    }
    buf.Write(ctx)
    fmt.Println(buf.String())
    fmt.Println("剩余缓冲大小: ", b.Buffered())
}

write

func bufIoWrite() {
    file := "./test-file"
    fd, err := os.OpenFile(file, os.O_RDWR, os.ModeAppend)
    if err != nil {
        panic(err)
    }
    defer fd.Close()
    cacheSize := 10
    b := bufio.NewWriterSize(fd, cacheSize)
    txt := []byte("world ")
    // 1、len(txt) + 已缓存大小 > cacheSize,则跳过缓存,直接向底层io.Writer中写入缓存中的数据,注意:超出缓存的部分不会写入
    // 2、len(ctx) + 已缓存大小 <= 缓存大小,则先将数据放到缓存中,调用flush后才会写入底层io.Writer
    if _, err := b.Write(txt); err != nil {
        panic(err)
    }
    cxt := make([]byte, 100)
    if _, err := fd.Read(cxt); err != nil {
        if err == io.EOF {
            fmt.Println("file is empty.")
        } else {
            panic(err)
        }
    }
    fmt.Println("before flush cache: ", string(cxt))
    fmt.Println("number of bytes that have been written into cache: ", b.Buffered())
    fmt.Println("how many bytes are unused in the cache: ", b.Available())
    // flush 将缓存中的数据写入到io.Writer
    if err := b.Flush(); err != nil {
       panic(err)
    }
    fmt.Println("after flush, number of bytes that have been written into cache: ", b.Buffered())
    fmt.Println("after flush, number of bytes are unused in the cache: ", b.Available())
    // os.OpenFile适合写入文件时使用,如果读取的话需要设置偏移量,使用ReadAt()
    // fd.ReadAt(cxt, 0) 从文件开头读取内容到cxt
    if _, err := fd.ReadAt(cxt, 0); err != nil {
        if err == io.EOF {
            fmt.Println("file is empty.")
        } else {
            panic(err)
        }
    }
    fmt.Println("after flush cache: ", string(cxt))
    file = "./test-file"
    fd1, err := os.Open(file)
    if err != nil {
       panic(err)
    }
    defer fd1.Close()
    b = bufio.NewWriterSize(fd, cacheSize)
    // readFrom 从别的文件中读取所有内容并写入到此文件,并不受b的缓存大小限制,且无需调用flush
    if _, err := b.ReadFrom(fd1); err != nil {
       panic(err)
    }
}

func bufIoScanner() {
    f, err := os.Open("./test-file")
    if err != nil {
        panic(err)
    }
    // 初始化一个scanner对象,按行分割文件内容
    scanner := bufio.NewScanner(f)
    // 扫描一次,即第一行
    scanner.Scan()
    fmt.Println(scanner.Text()) // 输出第一行
    // 输出剩余的所有行
    for scanner.Scan() {
        line := scanner.Text()
        fmt.Println(line)
    }
}

你可能感兴趣的:(golang)