首页 > 解决方案 > sftp用Python写操作原子性

问题描述

通过 SFTP 将行附加到远程文件时pysftp

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 字节行?

标签: pythonsshsftpatomicpysftp

解决方案


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

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

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


推荐阅读