我正在编写一个脚本,该脚本将轮询目录以查找新文件。
在这种情况下,是否有必要进行某种错误检查以确保文件在访问之前完全写入?
我不想在将文件完全写入磁盘之前使用它,但因为我想从文件中获取的信息接近开头,所以似乎可以提取我需要的数据而不需要意识到文件没有写完。
这是我应该担心的问题,还是文件被锁定,因为操作系统正在写入硬盘?
这是在Linux系统上。
答案 0 :(得分:6)
通常在Linux上,除非您使用某种类型的锁定,否则两个进程可以很高兴地同时打开同一个文件,即使是写入也是如此。有三种方法可以避免此问题:
<强>锁定强>
通过让编写器对文件应用锁定,可以防止阅读器部分地读取文件。但是,大多数锁都是建议性的,所以无论如何仍然完全可以看到部分结果。 (强制锁存在,但强烈不推荐,因为它们太脆弱了。)编写正确的锁定代码相对困难,将这些任务委托给专业库是正常的(即,到数据库引擎!)特别是,您不希望在网络文件系统上使用锁定;它在工作时会产生巨大的麻烦,而且经常会出错。
<强>公约强>
可以使用另一个名称在同一目录中创建一个文件,这个名称在阅读方面不会自动查找(例如.foobar.txt.tmp
),然后以原子方式重命名为正确的名称(例如,{{ 1}})一旦完成写作。这可以很好地工作,只要你注意处理以前运行无法正确写入文件的可能性。如果一次只有一个作家,这实现起来相当简单。
不用担心
经常编写的最常见文件类型是日志文件。这些可以很容易地编写,信息严格地只附加到文件中,因此任何读者都可以安全地查看文件的开头,而不必担心任何变化。这在实践中非常有效。
在任何这方面,Python都没有什么特别之处。在Linux上运行的所有程序都有同样的问题。
答案 1 :(得分:3)
在Unix上,除非编写应用程序不受影响,否则文件将不会被锁定,您将能够从中读取文件。
当然,读者必须准备好处理不完整的文件(请记住,作者可能会发生I / O缓冲)。
如果那是一个非首发,你将不得不考虑一些方案来同步作者和读者,例如:
答案 2 :(得分:0)
如果您对编写程序有一定的控制权,请将文件写在其他地方(如/ tmp目录),然后在完成后将其移动到正在监视的目录中。
如果您无法控制执行写入的程序(以及“控制”,我的意思是“编辑源代码”),您可能无法使其执行文件锁定,因此可能出。在这种情况下,您可能需要了解文件格式,以了解编写器何时完成。例如,如果编写器始终将“DONE”写为文件中的最后四个字符,则可以打开文件,搜索到最后,然后读取最后四个字符。
答案 3 :(得分:0)
是的,它会。
我更喜欢Donal所描述的“文件命名约定”和重命名解决方案。