当文件被删除时检测Python中损坏的流
我的问题是,当日志轮换时,Python 程序的日志记录会停止。 我已经追踪到了流本身。我没有看到任何方法来判断流是否从 python 中断。文件删除后,它仍然接受写入,没有任何问题。
import os
FILE = 'testing.txt'
fs = open(FILE, 'a')
fs.write('word')
os.remove(FILE)
fs.write('Nothing....') # Nothing breaks
print(fs.errors) # No errors
那么,如何确定文件流是否仍然有效呢? 检查文件是否存在也无济于事,因为无论流是否仍然有效,文件都将始终存在。
My problem is that logging stops for a python program when the log is rotated.
I have tracked it down to the stream itself. I don't see any way to tell if the stream is broken from python. After the file is deleted it still accepts writes without any issue.
import os
FILE = 'testing.txt'
fs = open(FILE, 'a')
fs.write('word')
os.remove(FILE)
fs.write('Nothing....') # Nothing breaks
print(fs.errors) # No errors
So, how can I find out if the file stream is still valid?
And checking to see if the file exists will not help since the file will always exist regardless of whether or not the stream is still valid.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
经过更多检查,我找到了解决方案。这是操作系统特定的问题。当文件在 Linux(或 Macintosh)中被删除时,它只是取消链接。 (我不知道这一点)
因此,如果您在计算机上运行 lsof,它仍然会将该文件显示为打开状态。
解决方案是在 python 中统计流。
这将为您提供其拥有的链接数量。
就这样吧。现在您知道是否应该重新加载它。希望这对其他人有帮助。
Upon much more inspection, I found the solution. It is an OS specific problem. When the file is deleted in Linux (or Macintosh) it just unlinks it. (I was not aware of this)
So if you run lsof on the machine, it still shows the file as open.
The solution is to stat the stream in python.
Which will give you the number of links it has.
And there you go. Now you know if you should reload it or not. Hopefully this helps someone else.
尝试异常处理:
Try Exception handling:
如果您需要更多的智能而不仅仅是
try: except:
子句,则可以使用 ionotify 的 python 绑定。但我认为它只与 Linux 有关(我不确定你的平台)There are python bindings for ionotify if you need more intelligence than just an
try: except:
clause. But I think its only pertinent to Linux (im not sure of your platform)我发现的另一个解决方案是将“copytruncate”标志添加到 logrotate 配置中。
有关更多信息,请参阅“man logrotate”。
Another solution I found is to add the "copytruncate" flag into the logrotate config.
See "man logrotate" for more info.