文件扫描程序循环未执行

时间:2019-11-25 11:35:02

标签: file go

我正在获取文本文件的最后一行,并尝试读取它。

获取最后一行:

func getLastLine(file *os.File) (result int) {
    s := bufio.NewScanner(file)
    result = 0
    for s.Scan() {
        result++
    }
    err := s.Err()
    if err != nil {
        log.Fatal(err)
    }
    return
}

读取文件:

func readFileFrom(file *os.File) {
    s := bufio.NewScanner(file)
    for s.Scan() {
        fmt.Println(s.Text())
    }

    err := s.Err()
    if err != nil {
        log.Fatal(err)
    }
}

如果我在main.go中写这个:

    getLastLine(file)
    readFileFrom(file)

它不会执行该块:

for s.Scan() {
    fmt.Println(s.Text())
}

如果我删除了getLastLine(file)行,则读数将按预期工作。

我认为这是因为2个扫描仪正在访问同一文件。

1 个答案:

答案 0 :(得分:2)

os.File保持下一个读或写操作将起作用的位置。读取/写入文件会更新该位置。

如果使用单个file,则将其传递到getLastLine()会一直读取到结尾,因此其指针将指向文件的末尾。现在将其传递给readFileFrom()将不会读取和打印任何内容,因为文件末尾(即“ end”的定义)之后没有更多数据。

您需要使用File.Seek()后退指针,或者需要关闭然后重新打开它。显然,仅倒带效率更高。要将指针设置为文件开始,请执行以下操作:

if _, err := file.Seek(0, io.SeekStart); err != nil {
    panic(err)
}

在两个函数调用之间执行此操作:

getLastLine(file)
if _, err := file.Seek(0, io.SeekStart); err != nil {
    panic(err)
}
readFileFrom(file)

还要注意,如果您将文件打开两次,则无需倒带,并且还可以同时运行这两个函数而不会互相干扰,因为它们仅读取文件,每个os.File有自己的指针。

file1, err := os.Open("a.txt")
// handle err
defer file1.Close()

file2, err := os.Open("a.txt")
// handle err
defer file2.Close()

wg := sync.WaitGroup()
wg.Add(1)
go func() {
    defer wg.Done()
    getLastLine(file1)
}()

readFileFrom(file2)

wg.Wait() // Wait for getLastLine() to complete
相关问题