1

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?

Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Alexander
  • 523
  • 5
  • 21

1 Answers1

3

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.
Shang Jian Ding
  • 1,931
  • 11
  • 24
  • 1
    `O_APPEND` isn't all that relevant, the same thing would happen if the file was being created, or even if it was being overwritten (given that the amount of data written is >= the previous size of the file). The only thing it comes down to is that the file position is at EOF when the writing is done. – hobbs Jul 02 '20 at 04:37
  • Right - if the file already exists and is larger than 20 bytes(per OP's code sample), then `O_APPEND` matters; otherwise it does not. – Shang Jian Ding Jul 02 '20 at 04:44