我在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中执行相同的操作。我是该语言的新手,所以不确定我所做的操作是否足够习惯/正确。
这是代码:
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一起使用。
可以调整睡眠时间,以满足特定需求。减少时间以降低延迟,并增加时间以减少CPU使用量。100ms的睡眠对于显示给人类的数据可能足够快。
问题内容: 输出logfile.txt的最后10行,然后随着文件的增长继续输出附加的数据。 在node.js 中做零件的推荐方式是什么? 以下输出整个文件(忽略“显示最后10行”),然后退出。 我知道事件循环正在退出,因为在流结束和关闭事件之后没有更多事件了-我很好奇继续监视流的最佳方法。 问题答案: 做到这一点的标准方法是使用。 另外,您可以只使用node-tail模块,该模块在内部使用并且已经
问题内容: 我想知道使用什么技术和/或库来实现linux命令“ ”的功能。我本质上是在寻找的附加组件/替代产品。客户端代码可能如下所示: 缺少的部分是的合理实现。它应该能够读取文件打开之前存在的部分以及添加的行。 问题答案: 能够继续读取文件,并等待文件有更多更新的能力,自己编写代码并不难。这是一些伪代码: 我假设你希望将这种功能放在其自己的线程中,以便可以使其hibernate而不影响应用程序的
问题内容: 将Docker for Mac 1.13.1与以下Dockerfile一起使用: 使用以下内容的contab文件: 当我使用以下命令构建和运行它时: 我看到输出: 如果我等待一分钟,则不会出现输出。但是,如果我登录到正在运行的容器并拖尾文件,则可以看到内容: 我尝试在CMD的末尾添加另一个回显,以查看是否只是吞没了STDOUT的最后一个命令,但这没有帮助。 我已经将代码发布在githu
问题内容: 我正在为Web应用程序编写日志文件查看器,为此,我想在日志文件的各行中进行分页。文件中的项目是基于行的,底部是最新的项目。 因此,我需要一种可以n从底部读取行并支持偏移量的方法。我想到的是这样的: 这是合理的方法吗?建议使用带偏移量尾部日志文件的推荐方式是什么? 问题答案:
问题内容: 您将如何实现一个包含文本区域的jsp站点,该文本区域显示(tomcat)服务器上的日志文件并自动刷新。 我认为刷新很容易使用setTimeout轮询到服务器并发送ajax请求。但是问题是如何监视服务器上的文件(它是一个Log4J日志文件- 也许我可以使用自己的附加程序?)进行更改,并在ajax请求到达时仅发送更改后的行? 我不知道如何检测日志中更改的行… 问题答案: ajax并每隔几秒
就是打印一个文件,并且监视,或者等待它的追加,如果有,就把追加的内容也打印.