Python会在写入完成前打开文件吗?
我正在写一个脚本,这个脚本会定期检查一个文件夹,看看有没有新文件。
在这种情况下,我需要做一些错误检查吗?也就是说,我要确保文件在被访问之前已经完全写入了吗?
我不想在文件还没完全写入磁盘之前就去使用它,但因为我想要的信息在文件的开头,所以我觉得可能在文件还没写完的时候就能提取到我需要的数据。
这是不是我需要担心的事情?或者说,文件会被锁住,因为操作系统正在往硬盘写入数据?
这是在一个Linux系统上。
4 个回答
如果你能控制写文件的程序,可以让它先把文件写到其他地方(比如/tmp目录),等写完了再把文件移动到你正在监视的目录里。
如果你不能控制这个写文件的程序(这里的“控制”是指“能编辑源代码”),那么你可能也无法让它进行文件锁定,所以这个方法可能不适用。在这种情况下,你可能需要了解一些文件格式的知识,才能知道写入操作什么时候完成。比如,如果这个程序总是在文件的最后四个字符写上“DONE”,那么你可以打开这个文件,跳到最后,读取最后四个字符。
在Linux系统上,通常情况下,除非你使用某种锁定机制,否则两个进程可以同时打开同一个文件,甚至是进行写入操作。为了避免出现问题,有三种方法:
锁定
通过让写入者对文件进行锁定,可以防止读取者部分读取文件。不过,大多数锁定是建议性的,所以读取者仍然有可能看到部分结果。(虽然存在强制锁定,但不推荐使用,因为它们非常脆弱。)编写正确的锁定代码相对困难,通常会把这类任务交给专业的库来处理(比如数据库引擎!)特别是,在网络文件系统上使用锁定会带来巨大的麻烦,虽然有时能正常工作,但也常常会出错。
约定
可以在同一个目录下创建一个不同名字的文件,这个名字在读取时不会被自动查找(例如,
.foobar.txt.tmp
),然后在写入完成后将其原子性地重命名为正确的名字(例如,foobar.txt
)。只要你注意处理之前的写入失败的情况,这种方法通常效果很好。如果每次只能有一个写入者,这种实现方式相对简单。不去担心
最常见的经常被写入的文件是日志文件。这些文件可以以一种方式轻松写入,使得信息只会被追加到文件末尾,因此任何读取者都可以安全地查看文件开头,而不必担心内容会在它面前改变。这种方法在实际操作中效果很好。
这些内容与Python没有什么特别的关系。在Linux上运行的所有程序都会面临同样的问题。
在Unix系统上,除非写入文件的程序特别设置了锁定,否则文件是不会被锁住的,你可以随意读取它。
不过,读取文件的人需要做好准备,可能会遇到不完整的文件(因为写入程序可能在进行输入输出缓冲)。
如果这样不行的话,你就得想办法让写入和读取的程序保持同步,比如:
- 明确地锁定文件;
- 先把数据写到一个临时位置,等文件写完了再把它移动到最终的位置(这个移动操作可以在同一个文件系统内安全地完成)。