Python+Paramiko編寫簡單的SFTP文件上傳下載工具類
在實(shí)際項(xiàng)目開發(fā)中,我們經(jīng)常需要通過 SFTP 協(xié)議與遠(yuǎn)程服務(wù)器進(jìn)行文件傳輸。Paramiko 是 Python 中最流行的 SSH2 協(xié)議實(shí)現(xiàn)庫,基于它我們可以輕松實(shí)現(xiàn) SFTP 客戶端功能。
本文將分享一個(gè)封裝好的 SftpClient 類,支持文件上傳、下載(帶重試機(jī)制)、上傳進(jìn)度提示以及連接管理,代碼簡潔實(shí)用,可直接拷貝到項(xiàng)目中使用。
環(huán)境準(zhǔn)備
首先確保安裝了 paramiko:
pip install paramiko
完整代碼實(shí)現(xiàn)
from paramiko import Transport, SFTPClient
import time
import errno
import logging
# 配置日志,便于觀察上傳進(jìn)度
logging.basicConfig(format='%(levelname)s : %(message)s',
level=logging.INFO)
class SftpClient:
_connection = None # 類級別共享的連接對象
def __init__(self, host, port, username, password):
self.host = host
self.port = port
self.username = username
self.password = password
self.create_connection(self.host, self.port,
self.username, self.password)
@classmethod
def create_connection(cls, host, port, username, password):
"""建立 SFTP 連接"""
transport = Transport(sock=(host, port))
transport.connect(username=username, password=password)
cls._connection = SFTPClient.from_transport(transport)
logging.info("SFTP 連接成功:{}@{}:{}".format(username, host, port))
@staticmethod
def uploading_info(uploaded_file_size, total_file_size):
"""上傳進(jìn)度回調(diào)函數(shù)"""
percentage = (uploaded_file_size / total_file_size) * 100
logging.info('已上傳:{} / {} ({:.2f}%)'.format(
uploaded_file_size, total_file_size, percentage))
def upload(self, local_path, remote_path):
"""上傳文件,支持進(jìn)度顯示"""
self._connection.put(localpath=local_path,
remotepath=remote_path,
callback=self.uploading_info,
confirm=True)
logging.info("文件上傳成功:{} -> {}".format(local_path, remote_path))
def file_exists(self, remote_path):
"""判斷遠(yuǎn)程文件是否存在"""
try:
self._connection.stat(remote_path)
return True
except IOError as e:
if e.errno == errno.ENOENT:
return False
raise # 其他錯(cuò)誤向上拋出
def download(self, remote_path, local_path, retry=5):
"""
下載文件
如果文件不存在,會等待5秒后重試,最多重試5次(適合文件正在生成場景)
"""
if self.file_exists(remote_path):
self._connection.get(remote_path, local_path)
logging.info("文件下載成功:{} -> {}".format(remote_path, local_path))
elif retry > 0:
logging.warning("遠(yuǎn)程文件不存在,{}秒后重試(剩余重試次數(shù):{})".format(5, retry))
time.sleep(5)
self.download(remote_path, local_path, retry=retry - 1)
else:
raise FileNotFoundError("下載失?。哼h(yuǎn)程文件 {} 不存在,且重試次數(shù)已用完".format(remote_path))
def close(self):
"""關(guān)閉連接"""
if self._connection:
self._connection.close()
logging.info("SFTP 連接已關(guān)閉")
if __name__ == '__main__':
# 請?zhí)鎿Q為真實(shí)的服務(wù)器信息
host = 'example.com'
port = 22
username = 'your_username'
password = 'your_password'
download_remote_path = 'outgoing/download.txt'
download_local_path = 'download.txt'
upload_local_path = 'upload.txt'
upload_remote_path = 'incoming/upload.txt'
# 使用示例
client = SftpClient(host, port, username, password)
# 上傳本地文件到遠(yuǎn)程服務(wù)器
client.upload(upload_local_path, upload_remote_path)
# 下載遠(yuǎn)程文件到本地(如果文件暫時(shí)不存在會自動(dòng)重試)
client.download(download_remote_path, download_local_path)
# 記得關(guān)閉連接
client.close()
功能亮點(diǎn)說明
進(jìn)度提示:上傳時(shí)通過 callback 參數(shù)實(shí)時(shí)打印上傳進(jìn)度,便于監(jiān)控大文件傳輸。
下載重試機(jī)制:在某些場景下(如遠(yuǎn)程服務(wù)器正在生成文件),文件可能暫時(shí)不存在。該方法會自動(dòng)等待并重試 5 次,避免立即失敗。
連接管理:使用類變量 _connection 共享連接,避免重復(fù)創(chuàng)建 Transport,提高效率。
異常處理:file_exists 方法優(yōu)雅處理“文件不存在”錯(cuò)誤,其他異常正常拋出。
日志友好:使用 logging 輸出關(guān)鍵信息,便于生產(chǎn)環(huán)境排查問題。
使用注意事項(xiàng)
請務(wù)必將密碼等敏感信息改為配置文件或環(huán)境變量方式讀取,不要硬編碼在代碼中。
如果服務(wù)器使用密鑰認(rèn)證,可將 transport.connect 改為 pkey 參數(shù)傳入私鑰。
大文件傳輸時(shí)建議適當(dāng)調(diào)整服務(wù)器的超時(shí)配置,避免連接中斷。
總結(jié)
這個(gè) SftpClient 類已經(jīng)可以滿足大部分日常 SFTP 文件傳輸需求,代碼結(jié)構(gòu)清晰、易于擴(kuò)展。如果需要支持目錄遞歸上傳/下載、斷點(diǎn)續(xù)傳等高級功能,可以在此基礎(chǔ)上繼續(xù)封裝。
到此這篇關(guān)于Python+Paramiko編寫簡單的SFTP文件上傳下載工具類的文章就介紹到這了,更多相關(guān)Python SFTP文件上傳下載工具類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解
這篇文章主要介紹了Python數(shù)據(jù)清洗之利用pandas篩選數(shù)據(jù)詳解,Pandas是一個(gè)用于數(shù)據(jù)分析和處理的Python庫,它提供了高效的數(shù)據(jù)結(jié)構(gòu)和數(shù)據(jù)分析工具,使得數(shù)據(jù)的清洗、轉(zhuǎn)換、分析和可視化變得更加容易和靈活,需要的朋友可以參考下2023-08-08
Python中使用tarfile壓縮、解壓tar歸檔文件示例
這篇文章主要介紹了Python中使用tarfile壓縮、解壓tar歸檔文件示例,本文直接給出解壓和壓縮代碼示例,需要的朋友可以參考下2015-04-04
利用PyQt5中QLabel組件實(shí)現(xiàn)亞克力磨砂效果
Windows10 在 UWP 應(yīng)用中支持亞克力畫刷,可以在部件的底部繪制亞克力效果的背景圖。本文將使用QLabel來模擬這個(gè)磨砂過程,感興趣的可以了解一下2022-03-03
Python數(shù)據(jù)類型相互轉(zhuǎn)換
當(dāng)涉及數(shù)據(jù)類型轉(zhuǎn)換時(shí),Python提供了多種內(nèi)置函數(shù)來執(zhí)行不同類型之間的轉(zhuǎn)換,本文主要介紹了Python數(shù)據(jù)類型相互轉(zhuǎn)換,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09
pygame實(shí)現(xiàn)一個(gè)類似滿天星游戲流程詳解
這篇文章主要介紹了使用pygame來編寫類滿天星游戲的全記錄,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2022-09-09
python使用paramiko執(zhí)行服務(wù)器腳本并拿到實(shí)時(shí)結(jié)果
這篇文章主要介紹了python使用paramiko執(zhí)行服務(wù)器腳本并拿到實(shí)時(shí)結(jié)果,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-12-12
python實(shí)現(xiàn)K近鄰回歸,采用等權(quán)重和不等權(quán)重的方法
今天小編就為大家分享一篇python實(shí)現(xiàn)K近鄰回歸,采用等權(quán)重和不等權(quán)重的方法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-01-01

