如何打印目录中文件的内容但忽略在写入模式下打开的文件?
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何打印目录中文件的内容但忽略在写入模式下打开的文件?相关的知识,希望对你有一定的参考价值。
我有一个goroutine,定期检查目录中的新文件,然后打印文件的内容。然而,还有另一个goroutine创建一个文件,将内容写入其中,然后保存文件。
如何忽略目录中以WRITE模式打开的文件?
示例代码:
for {
fileList, err := ioutil.ReadDir("/uploadFiles")
if err != nil {
log.Fatal(err)
continue
}
for _, f := range fileList {
log.Println("File : ", f.Name())
go printContents(f.Name())
}
time.Sleep(time.Second * 5)
}
在printContents goroutine中,我想忽略在WRITE模式下打开的文件。
答案
这不是它的完成方式。
在我的头脑中,我可以想到这些选项:
- 如果两个goroutine都在同一个程序中工作,那么几乎没有问题:让“producer”goroutine将已经完成修改的文件的名称注册到某个注册表中,并使该“注册表”中的“consumer”goroutine读取(和删除) 。 在最简单的情况下,可以是缓冲通道。 如果生产者的工作速度比消费者快得多,并且您不希望由于某种原因阻止前者,那么受互斥锁保护的切片将适合该账单。
- 如果goroutine在同一台机器上的不同进程中工作,但您控制两个程序,则让生产者进程通过任何合适的IPC将相同的数据传递给使用者进程。 做什么方法IPC更好取决于流程如何启动,交互等。 有各种各样的选择。
- 如果您控制两个进程但不想在它们之间混淆IPC(也有原因),那么让生产者遵循如何编写文件的最佳实践(稍后会详细介绍),并让消费者使用任何文件系统监视工具,用于报告生成器生成后创建(“出现”)哪些文件。你可以从
github.com/fsnotify/fsnotify
开始。 为了正确地写入文件,生产者必须将其数据写入临时文件 - 即位于同一目录但具有文件名的文件,该文件很好地理解为表明文件尚未完成 - 例如, “.foobar.data.part”或“foobar.data.276gd14054.tmp”可以写“foobar.data”。 (存在其他方法,但这个方法足以开始。) 文件准备好后,生产者必须将文件从其临时名称重命名为“正确”的最终名称。这个操作在所有敏感的操作系统/文件系统上都是原子操作,并使文件从消费者的PoV原子上“弹出存在”。例如,inotify
on Linux generates an event of type "moved to" for such an appearance。 如果你不想自己做正确的事,github.com/dchest/safefile
是一个很好的跨平台开始。 正如您所看到的,使用这种方法,您知道文件只是根据报告显示的事实完成的。 - 如果你不控制制片人,你可能需要求助于猜测。 simpest再次监视文件系统的事件 - 但这次是“文件更新”事件,而不是“文件创建”事件。对于报告为已更新的每个文件,您必须记住该事件的时间戳,并且当经过一定时间后,您可以声明该文件由生产者完成。 IMO这种方法是最糟糕的,但如果你没有更好的选择,那至少是一些东西。
以上是关于如何打印目录中文件的内容但忽略在写入模式下打开的文件?的主要内容,如果未能解决你的问题,请参考以下文章