问题
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)
回答1:
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.
来源:https://stackoverflow.com/questions/42245227/golang-a-proper-way-to-rewind-file-pointer