Search code examples
gobufferedreaderfilereaderbufferedwriter

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


Codes are shown as follow:

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.")
        }
    }
}

I can't read the content already write to the file.

It seems that the offset of the file point to the end of file.

Could someone explain why this happens?


Solution

  • O_APPEND causes the offset of the file descriptor to advance to the end of the file before each write. Each write advances the offset of the file descriptor by the number of bytes successfully written.

    Add the following before your //read line:

        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)
    

    And you'll see that your program now works correctly.


    Reference:

    From the man page of 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.
    

    From the man page of 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.