用Python实现sftp写操作原子性
使用用Python实现sftp写操作原子性,python,ssh,sftp,atomicity,pysftp,Python,Ssh,Sftp,Atomicity,Pysftp,使用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):
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 >代码>写在远程文件上。
在其他情况下,最后一行在中间被截断,在进程中断时。
<强>有没有办法使SFFT<代码> F.Wrd/S代码>原子?< /强>要么就是在中间失败,要么写不出来,要么成功,写完整的40’01字节行。< /P> < P> >我不相信这是可能的。首先,为了使其成为可能,远程系统的
write(2)
syscall必须保证这一点,并且POSIX不需要这种行为。写入可能是非原子性的原因有很多,例如,如果远程磁盘已满,您只能将部分数据写入磁盘,或者如果远程用户有配额,您的完全写入将超过该配额
此外,您试图通过网络连接写入超过40KB的数据,这很可能不适合一个数据包。因此,任何网络软件编写这么大的数据包都没有意义
如果完全写入或根本不写入文件对您很重要,您可以写入同一磁盘上的另一个文件,然后重命名原始文件。这就是Git等程序保证原子文件更新的方式。我认为对于SFTP,它要求双方都支持posix-rename@openssh.com扩展;OpenSSH有,但我不知道pysftp是否有,所以您需要查阅文档。谢谢您的回答。您可以写入同一磁盘上的另一个文件,然后在原始文件上重命名:这就是我在发送全新文件时所做的:sftp.put(f,'myfile.tmp')
和sftp.rename('myfile.tmp','myfile')
成功完成后。(1/2)(2/2)但在向现有的远程2GB文件追加(在a+
模式下打开)时,我无法将该文件复制到myfile.tmp
每当我想追加100KB时,删除原始的myfile
,将myfile.tmp
重命名为myfile
,如果将2GB重新写入只追加100KB,这将是非常不有效的。