【问题标题】:Golang, a proper way to rewind file pointerGolang,倒带文件指针的正确方法
【发布时间】:2017-07-03 20:51:06
【问题描述】:
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)
        }

    }
}

我在这里使用两个阅读器来读取 csv 文件。 要倒带我使用data.Seek(0, 0) 的文件,这是一个好方法吗?或者最好在二读之前关闭文件并再次打开。

*File 用作io.Reader 是否也正确?或者最好是r := ioutil.NewReader(data)

【问题讨论】:

    标签: file go io


    【解决方案1】:

    按照您的建议,使用File.Seek(0, 0)(或更安全地使用常量:File.Seek(0, io.SeekStart))最容易找到文件的开头,但不要忘记:

    未指定使用 O_APPEND 打开的文件上的 Seek 行为。

    (但这不适用于您的示例。)

    将指针设置到文件的开头总是比关闭和重新打开文件快得多。如果您需要交替读取文件的不同“小”部分多次,那么也许打开文件两次以避免重复查找可能是有利可图的(担心仅当您遇到性能问题时才考虑此问题)。

    同样,*os.File 实现了io.Reader,因此您可以将其用作io.Reader。我不知道您在问题中提到了什么ioutil.NewReader(data)(包io/ioutil 没有这样的功能;也许您的意思是bufio.NewReader()?),但肯定不需要从文件中读取。

    【讨论】:

    • 我不明白,因为Seek 的签名是Seek(offset int64, whence int) 并且常量与whence 值相关,所以它必须是File.Seek(0, io.SeekStart) 而不是相反。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-02-29
    • 2019-10-27
    • 2014-07-30
    • 2015-10-07
    • 1970-01-01
    • 2010-09-18
    • 2013-03-12
    相关资源
    最近更新 更多