python通過sftp遠端傳輸檔案
阿新 • • 發佈:2018-12-03
python提供了一個第三方模組paramiko,通過這個模組可以實現兩臺機器之間的網路連線,sftp是paramiko的一個方法,使用sftp可以在兩臺機器之間互相傳輸 拷貝檔案。然而paramiko的sftp只能拷貝檔案,不能拷貝資料夾。要實現資料夾的拷貝,可以這樣子思考:使用深度搜索遍歷源目錄,若是檔案,直接拷貝到 目的目錄;若是資料夾,則先在目的目錄建立一個子目錄,然後遍歷子目錄...使用遞迴函式,可以達到完全拷貝目錄的目的。實現程式碼如下:
1.獲取一個sftp控制代碼
import
paramiko
#建立連線,獲取sftp控制代碼
def
sftp_connect(username,password,host,port
=
22
):
client
=
None
sftp
=
None
try
:
client
=
paramiko.Transport((host,port))
except
Exception as error:
print
error
else
:
try
:
client.connect(username
=
username, password
=
password)
except
Exception as error:
print
error
else
:
sftp
=
paramiko.SFTPClient.from_transport(client)
return
client,sftp
#斷開連線
def
disconnect(client):
try
:
client.close()
except
Exception as error:
print
error
2.從遠端機器上下載檔案(夾)到本地
import
os
import
sys
from
stat
import
S_ISDIR as isdir
def
_check_local(local):
if
not
os.path.exists(local):
try
:
os.mkdir(local)
except
IOError as err:
print
err
def
get(sftp,remote,local):
#檢查遠端檔案是否存在
try
:
result
=
sftp.stat(remote)
except
IOError as err:
error
=
'[ERROR %s] %s: %s'
%
(err.errno,os.path.basename(os.path.normpath(remote)),err.strerror)
print
error
else
:
#判斷遠端檔案是否為目錄
if
isdir(result.st_mode):
dirname
=
os.path.basename(os.path.normpath(remote))
local
=
os.path.join(local,dirname)
_check_local(local)
for
file
in
sftp.listdir(remote):
sub_remote
=
os.path.join(remote,
file
)
sub_remote
=
sub_remote.replace(
'\\','
/
')
get(sftp,sub_remote,local)
else
:
#拷貝檔案
if
os.path.isdir(local):
local
=
os.path.join(local,os.path.basename(remote))
try
:
sftp.get(remote,local)
except
IOError as err:
print
err
else
:
print
'[get]'
,local,
'<=='
,remote
3.從本地拷貝檔案(夾)到遠端機器
import
os
def
put(sftp,local,remote):
#檢查路徑是否存在
def
_is_exists(path,function):
path
=
path.replace(
'\\','
/
')
try
:
function(path)
except
Exception as error:
return
False
else
:
return
True
#拷貝檔案
def
_copy(sftp,local,remote):
#判斷remote是否是目錄
if
_is_exists(remote,function
=
sftp.chdir):
#是,獲取local路徑中的最後一個檔名拼接到remote中
filename
=
os.path.basename(os.path.normpath(local))
remote
=
os.path.join(remote,filename).replace(
'\\','
/
')
#如果local為目錄
if
os.path.isdir(local):
#在遠端建立相應的目錄
_is_exists(remote,function
=
sftp.mkdir)
#遍歷local
for
file
in
os.listdir(local):
#取得file的全路徑
localfile
=
os.path.join(local,
file
).replace(
'\\','
/
')
#深度遞迴_copy()
_copy(sftp
=
sftp,local
=
localfile,remote
=
remote)
#如果local為檔案
if
os.path.isfile(local):
try
:
sftp.put(local,remote)
except
Exception as error:
print
error
print
'[put]'
,local,
'==>'
,remote,
'FAILED'
else
:
print
'[put]'
,local,
'==>'
,remote,
'SUCCESSED'
#檢查local
if
not
_is_exists(local,function
=
os.stat):
print
"'"+local+"': No such file or directory in local"
return False
#檢查remote的父目錄
remote_parent = os.path.dirname(os.path.normpath(remote))
if not _is_exists(remote_parent,function=sftp.chdir):
print "'"
+
remote
+
"': No such file or directory in remote"
return
False
#拷貝檔案
_copy(sftp
=
sftp,local
=
local,remote
=
remote)