最近一個同步數據的需求,需要把壓縮包自動上傳到VPS上。
基于安全性的考慮,不能使用FTP,就只能走SFTP協議。而且考慮到網絡卡斷的問題,還必須要有斷點續傳的功能。
用python操作sftp,自然首選是paramiko庫。操作就跟之前操作FTP類似。但是斷電續傳什么的可就難住我了,因為一直在玩文件操作,也就是open, 然后read/write, 最后close。
SFTP斷電續傳什么的,臣妾做不到啊。
只能求助stackoverflow了,一個達人指點我說,可以用計算已上傳的文件大小,然后在把缺少的補上。原理大家都懂,這個關鍵是這個達人告訴了我對應的SFTP的函數。
于是寫出如下代碼:
# -*- coding:utf-8 -*-
import config
import paramiko
import os
privatekeyfile = os.path.expanduser('~/.ssh/id_rsa')
mykey = paramiko.RSAKey.from_private_key_file(privatekeyfile)
transport = paramiko.Transport((config.host, config.port))
transport.connect(username=config.username, pkey=mykey)
sftp = paramiko.SFTPClient.from_transport(transport)
remot_dir = 'xxx/xxx/xxx'
local_dir = 'xxx/xxx/xxx'
filename = 'xxx.tar'
file_list = sftp.listdir(remot_dir)
if filename in file_list:
stat = sftp.stat(remot_dir + filename)
f_local = open(local_dir + filename)
f_local.seek(stat.st_size)
f_remote = sftp.open(remot_dir + filename, "a")
tmp_buffer = f_local.read(100000)
while tmp_buffer:
f_remote.write(tmp_buffer)
tmp_buffer = f_local.read(100000)
f_remote.close()
f_local.close()
else:
f_local = open(local_dir + filename)
f_remote = sftp.open(remot_dir + filename, "w")
tmp_buffer = f_local.read(100000)
while tmp_buffer:
f_remote.write(tmp_buffer)
tmp_buffer = f_local.read(100000)
f_remote.close()
f_local.close()
sftp.close()
transport.close()
我測試了一下,手動斷網再鏈接,壓縮文件正確上傳玩了。不放心的同學還可以搞個MD5校驗下。