4

I want to write something to a file then read them from the same *os.File pointer. But nothing is read

package main

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

func main() {
    filename := "test.txt"
    f, _ := os.OpenFile(filename, os.O_CREATE|os.O_TRUNC|os.O_RDWR, os.ModePerm)
    defer os.Remove(filename)
    // write 10 times
    for i := 0; i < 10; i++ {
        fmt.Fprintf(f, "test%d\n", i)
    }
    // read 10 times
    r := bufio.NewReader(f)
    for i := 0; i < 10; i++ {
        str, _, err := r.ReadLine()
        if err != nil {
            if err == io.EOF {
                fmt.Println("Done")
                return
            }
            fmt.Println("Error", err)
        }
        fmt.Println("Read", string(str))
    }
}

The program always print "Done" text

0

1 Answer 1

8

When you write to an os.File it moves the current file position pointer. It means after the write file loop the file pointer is at the end of the file.

Now if you try to read from the file you as expected get io.EOF instantly, because you're at the end of the file.

To resolve it you must Seek to the beginning of the file first, before you read from it.

_, err := f.Seek(0, 0)
if err != nil {
    fmt.Println("Error", err)
}
Sign up to request clarification or add additional context in comments.

6 Comments

Or, to put it another way, there is a single (shared) file offset. Note that on many OSes, the underlying OS-level file descriptor has a single shared offset as well, so that if the file is open in separate processes, they can interfere with each other (or communicate with each other!) by messing with the descriptor offset.
@torek Thanks for that. Didn't know that fd's have a single shared offset!
@torek I'm not sure different FDs share the offset.
@shmsr (and zerkms but can only @ one and only one needed here anyway) On Unix/Linux, it depends on how you arranged to get the file descriptor. If it's dup()ed or equivalent, it shares the offset. If it is a separate open() or equivalent, it does not. On other systems, well, they vary. :-) (Note further that BSD style AF_UNIX sockets allow you to pass file descriptors around between processes.)
@torek in the question's code it's os.OpenFile.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.