bufio.Reader 在 bufio.Writer 写入后从文件中读取任何内容

bufio.Reader read nothing from the file after bufio.Writer write

代码如下:

package main

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

func main() {
    file, _ := os.OpenFile("test.txt", os.O_CREATE|os.O_RDWR|os.O_APPEND, 0666)

    // write
    writer := bufio.NewWriter(file)
    for i := 0; i < 10; i++ {
        fmt.Fprintln(writer, i)
    }
    writer.Flush()

    // read
    reader := bufio.NewReader(file)
    for {
        line, _, err := reader.ReadLine()
        log.Println(string(line))
        if err == io.EOF {
            break
        }
        if err != nil {
            log.Fatalln("get msg failed.")
        }
    }
}

我无法读取已写入文件的内容。

文件的偏移量似乎指向文件末尾。

有人可以解释为什么会这样吗?

O_APPEND 使文件描述符的偏移量在每次写入前提前到文件末尾。每次写入都会将文件描述符的偏移量增加成功写入的字节数。

//read 行之前添加以下内容:

    offset, _ := file.Seek(0, io.SeekCurrent)
    fmt.Printf("DEBUG: before: file offset is %d\n", offset)
    file.Seek(0, 0)
    offset, _ = file.Seek(0, io.SeekCurrent)
    fmt.Printf("DEBUG: after: file offset is %d\n", offset)

你会发现你的程序现在可以正常工作了。


参考:

来自 open 的手册页:

       O_APPEND
              The file is opened in append mode.  Before each write(2), the
              file offset is positioned at the end of the file, as if with
              lseek(2).  The modification of the file offset and the write
              operation are performed as a single atomic step.

来自 write 的手册页:

       For a seekable file (i.e., one to which lseek(2) may be applied, for
       example, a regular file) writing takes place at the file offset, and
       the file offset is incremented by the number of bytes actually
       written.  If the file was open(2)ed with O_APPEND, the file offset is
       first set to the end of the file before writing.  The adjustment of
       the file offset and the write operation are performed as an atomic
       step.