sftp使用Python编写操作原子性



使用pysftp:通过SFTP向远程文件追加行时

import pysftp
with pysftp.Connection('192.168.0.2', username='root', password='') as sftp:    
with sftp.cd('/home/www/test'):
with sftp.open('test.txt', 'a+') as f:
for i in range(100):
s = (("%04d" % i).encode()*10000) + b'n'  # 40'001 bytes
f.write(s)

如果我在操作过程中终止进程,有时(如果幸运的话(,整行s都会写在远程文件上。

在其他情况下,最后一行在中间被截断,此时进程已被中断。

有没有办法使SFTPf.write(s)操作原子化即,要么它在中间失败,然后什么都不写,要么它成功,然后写入了整个40'001字节行?

我认为这是不可能的。首先,为了使其成为可能,远程系统的write(2)系统调用必须保证这一点,而POSIX不需要这种行为。写入可能是非原子的原因有很多,例如远程磁盘已满,您只能将部分数据写入磁盘,或者远程用户有配额,您的完全写入将超过配额。

此外,您正试图通过网络连接写入超过40kB的数据,但很可能这不适合一个数据包。因此,任何网络软件编写这么大的数据包都是没有意义的。

如果完整或根本不写入文件对您来说很重要,您可以写入同一磁盘上的另一个文件,然后在原始文件上重命名。这就是像Git这样的程序保证原子文件更新的方式。我认为SFTP需要双方支持posix-rename@openssh.com扩展;OpenSSH有,但我不知道pysftp是否有,所以您需要查阅文档。

最新更新