python - 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 字节行?
解决方案
我不相信这是可能的。首先,为了使它成为可能,远程系统的write(2)
系统调用必须保证这一点,而 POSIX 不需要这种行为。写入可能是非原子的有很多原因,例如远程磁盘已满,您只能将部分数据写入磁盘,或者远程用户有配额并且您的完整写入将超过该配额。
此外,您正在尝试通过网络连接写入超过 40 kB 的数据,并且很可能不适合一个数据包。因此,任何网络软件编写这么大的数据包都是没有意义的。
如果完全写入文件或根本不写入文件对您很重要,您可以写入同一磁盘上的另一个文件,然后重命名原始文件。这是像 Git 这样的程序保证原子文件更新的方式。我相信对于需要双方都支持posix-rename@openssh.com
扩展的 SFTP;OpenSSH 可以,但我不知道是否pysftp
可以,因此您需要查阅文档。
推荐阅读
- vector - 如何从向量的向量中打印第 n 个索引
- xcode - Xcode在xcode10.3中找不到头文件
- javascript - 如何使用 getStats api
- reactjs - 如何在重定向之前防止组件显示?
- angular - 错误 TS1005:应为“>”。node_modules/@tensorflow/tfjs-layers/dist/engine/training_utils.d.ts
- ios - 如何禁用 webView 中的弹出窗口?
- c# - 是否有用于电话号码验证的正则表达式?
- mysql - 由于非唯一值,如何更快地在列中找到完全匹配,而不需要索引
- dialogflow-es - Dialogflow 按钮回发处理
- python - xarray - 从另一个 DataArray 的时间标签中选择/索引 DataArray