Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Golang, a proper way to rewind file pointer

Tags:

package main

import (
    "bufio"
    "encoding/csv"
    "fmt"
    "io"
    "log"
    "os"
)

func main() {
    data, err := os.Open("cc.csv")
    defer data.Close()
    if err != nil {
        log.Fatal(err)
    }

    s := bufio.NewScanner(data)
    for s.Scan() {
        fmt.Println(s.Text())
        if err := s.Err(); err != nil {
            panic(err)
        }
    }
    // Is it a proper way?
    data.Seek(0, 0)
    r := csv.NewReader(data)

    for {
        if record, err := r.Read(); err == io.EOF {

            break
        } else if err != nil {
            log.Fatal(err)
        } else {
            fmt.Println(record)
        }

    }
}

I use two readers here to read from a csv file. To rewind a file I use data.Seek(0, 0) is it a good way? Or it's better to close the file and open again before second reading.

Is it also correct to use *File as an io.Reader ? Or it's better to do r := ioutil.NewReader(data)

like image 216
Shadowfax Avatar asked Feb 15 '17 09:02

Shadowfax


People also ask

How do you reset a file pointer?

When you open an os. File and read some or all its contents, the file pointer offset will be set to the last line that was read. If you want to reset the pointer to the beginning of the file, you need to call the Seek() method on the file.

How do I change the file pointer to the beginning of a file?

fseek(fptr, 0, SEEK_SET); to reset the pointer to the start of the file. You cannot do that for stdin . If you need to be able to reset the pointer, pass the file as an argument to the program and use fopen to open the file and read its contents.

How do you go back to the beginning of a file in C?

C library function - rewind() The C library function void rewind(FILE *stream) sets the file position to the beginning of the file of the given stream.

What is the use of rewind () functions?

rewind() — Adjust Current File Position The rewind() function repositions the file pointer associated with stream to the beginning of the file. A call to the rewind() function is the same as: (void)fseek(stream, 0L, SEEK_SET); except that the rewind() function also clears the error indicator for the stream.


1 Answers

Seeking to the beginning of the file is easiest done using File.Seek(0, 0) (or more safely using a constant: File.Seek(0, io.SeekStart)) just as you suggested, but don't forget that:

The behavior of Seek on a file opened with O_APPEND is not specified.

(This does not apply to your example though.)

Setting the pointer to the beginning of the file is always much faster than closing and reopening the file. If you need to read different, "small" parts of the file many times, alternating, then maybe it might be profitable to open the file twice to avoid repeated seeking (worry about this only if you have peformance problems).

And again, *os.File implements io.Reader, so you can use it as an io.Reader. I don't know what ioutil.NewReader(data) is you mentioned in your question (package io/ioutil has no such function; maybe you meant bufio.NewReader()?), but certainly it is not needed to read from a file.

like image 94
icza Avatar answered Oct 24 '22 03:10

icza