如何在命名管道中的 EOF 之后恢复读取
Posted
技术标签:
【中文标题】如何在命名管道中的 EOF 之后恢复读取【英文标题】:How to resume reading after EOF in named pipe 【发布时间】:2017-03-26 08:44:26 【问题描述】:我正在编写一个程序,它打开一个命名管道进行读取,然后处理写入该管道的所有行:
err = syscall.Mkfifo("/tmp/myfifo", 0666)
if err != nil
panic(err)
pipe, err := os.OpenFile("/tmp/myfifo", os.O_RDONLY, os.ModeNamedPipe)
if err != nil
panic(err)
reader := bufio.NewReader(pipe)
scanner := bufio.NewScanner(reader)
for scanner.Scan()
line := scanner.Text()
process(line)
只要写入过程不重新启动或由于其他原因发送 EOF,此方法就可以正常工作。发生这种情况时,循环终止(正如 Scanner
的规范所预期的那样)。
但是,我想保持管道打开以接受进一步的写入。我可以当然只是重新初始化扫描仪,但我相信这会产生一个竞争条件,即扫描仪可能尚未准备好,而新进程已开始写入管道。
还有其他选择吗?我需要直接使用File
类型吗?
【问题讨论】:
你需要一台新的扫描仪,哪里会有比赛? @JimB 我担心的是作者断开连接,我得到一个 EOF 并退出循环以重新创建扫描仪。在此完成之前,写入器已重新启动并继续写入管道。可能这只会导致写入被缓冲?我想这取决于我是否还需要关闭文件句柄。 【参考方案1】:来自bufio GoDoc:
Scan ... 在扫描停止时返回 false,无论是到达输入末尾还是错误。
因此您可以让文件保持打开并读取直到 EOF,然后在文件更改或定期(即创建一个 goroutine)时再次触发 scanner.Scan()
,并确保 pipe
变量不超出范围,以便您可以再次引用它。
如果我正确理解您对竞态条件的担忧,这将不是问题(除非必须同步写入和读取操作),但是当重新初始化扫描仪时,它最终会回到文件的开头.
【讨论】:
同样来自文档:Scanning stops unrecoverably at EOF
-- 你不能再调用 Scan 了。以上是关于如何在命名管道中的 EOF 之后恢复读取的主要内容,如果未能解决你的问题,请参考以下文章