1. 程式人生 > >python通過sftp遠端傳輸檔案

python通過sftp遠端傳輸檔案

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)