gpt4 book ai didi

file - "tail -f"类生成器

转载 作者:IT老高 更新时间:2023-10-28 13:09:18 26 4
gpt4 key购买 nike

我在 Python 中有这个方便的函数:

def follow(path):
with open(self.path) as lines:
lines.seek(0, 2) # seek to EOF

while True:
line = lines.readline()
if not line:
time.sleep(0.1)
continue
yield line

它做一些类似于 UNIX tail -f 的事情:你会得到文件的最后几行。这很方便,因为您可以在不阻塞的情况下获取生成器并将其传递给另一个函数。

然后我不得不在 Go 中做同样的事情。我是这门语言的新手,所以我不确定我所做的对于 Go 来说是否足够地道/正确。

代码如下:

func Follow(fileName string) chan string {

out_chan := make(chan string)

file, err := os.Open(fileName)
if err != nil {
log.Fatal(err)
}

file.Seek(0, os.SEEK_END)
bf := bufio.NewReader(file)

go func() {
for {
line, _, _ := bf.ReadLine()

if len(line) == 0 {
time.Sleep(10 * time.Millisecond)
} else {
out_chan <- string(line)
}
}

defer file.Close()
close(out_chan)
}()

return out_chan
}

在 Go 中有没有更简洁的方法来做到这一点?我有一种感觉,对这样的事情使用异步调用有点过头了,这真的让我很困扰。

最佳答案

为在 EOF 上休眠的阅读器创建一个包装器:

type tailReader struct {
io.ReadCloser
}

func (t tailReader) Read(b []byte) (int, error) {
for {
n, err := t.ReadCloser.Read(b)
if n > 0 {
return n, nil
} else if err != io.EOF {
return n, err
}
time.Sleep(10 * time.Millisecond)
}
}

func newTailReader(fileName string) (tailReader, error) {
f, err := os.Open(fileName)
if err != nil {
return tailReader{}, err
}

if _, err := f.Seek(0, 2); err != nil {
return tailReader{}, err
}
return tailReader{f}, nil
}

这个阅读器可以在任何可以使用 io.Reader 的地方使用。下面是如何使用 bufio.Scanner 遍历行:

t, err := newTailReader("somefile")
if err != nil {
log.Fatal(err)
}
defer t.Close()
scanner := bufio.NewScanner(t)
for scanner.Scan() {
fmt.Println(scanner.Text())
}
if err := scanner.Err(); err != nil {
fmt.Fprintln(os.Stderr, "reading:", err)
}

阅读器还可以用于循环附加到文件中的 JSON 值:

t, err := newTailReader("somefile")
if err != nil {
log.Fatal(err)
}
defer t.Close()
dec := json.NewDecoder(t)
for {
var v SomeType
if err := dec.Decode(&v); err != nil {
log.Fatal(err)
}
fmt.Println("the value is ", v)
}

与问题中概述的 goroutine 方法相比,这种方法有几个优点。首先是关机很容易。只需关闭文件。无需通知 goroutine 它应该退出。第二个优点是许多包都可以与 io.Reader 一起使用。

sleep 时间可以上下调整以满足特定需求。减少时间以降低延迟并增加时间以减少 CPU 使用。对于向人类显示的数据来说,100 毫秒的 sleep 可能已经足够快了。

关于file - "tail -f"类生成器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31120987/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com