ftp、sftp文件传输

ftp

#!/usr/bin/python
# -*- coding: UTF-8 -*-

from ftplib import FTP
import os


class MyFtp:
    def __init__(self, host=None, port=21, username=None, password=None):
        self.ftp = FTP()
        # 重新设置下编码方式
        self.ftp.encoding = 'utf-8'
        try:
            # 0主动模式 1 #被动模式
            self.ftp.set_pasv(True)
            self.ftp.connect(host, port)
            self.ftp.login(username, password)
            print('成功连接到:', host, "登录成功...")
        except Exception as err:
            print("FTP 连接或登录失败,错误描述为:", err)

    def __del__(self):
        print("关闭连接")
        self.ftp.quit()

    def is_same_size(self, local_file, remote_file):
        # 判断文件大小是否相等
        try:
            remote_file_size = self.ftp.size(remote_file)
        except Exception as err:
            # print("is_same_size() 错误描述为:%s" % err)
            remote_file_size = -1
        try:
            local_file_size = os.path.getsize(local_file)
        except Exception as err:
            # print("is_same_size() 错误描述为:%s" % err)
            local_file_size = -1
        # print(f'local_file_size:{local_file_size}, remote_file_size:{remote_file_size}')
        if remote_file_size == local_file_size:
            return 1
        else:
            return 0

    def download_file(self, remote_file, local_file):
        remote_file = remote_file if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_file
        print(f"下载文件: {remote_file} ---> {local_file}")
        if self.is_same_size(local_file, remote_file):
            print("文件大小相同,此文件跳过")
        else:
            try:
                buf_size = 1024
                file_handler = open(local_file, 'wb')
                self.ftp.retrbinary(f'RETR {remote_file}', file_handler.write, blocksize=buf_size)
                file_handler.close()
            except Exception as err:
                print(f'下载文件出错,出现异常:{err}')

    def download_dir(self, remote_dir, local_dir):
        remote_dir = remote_dir if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_dir
        print(f"下载目录: {remote_dir} ---> {local_dir}")
        try:
            self.ftp.cwd(remote_dir)
            print(f'切换至目录: {self.ftp.pwd()}')
        except Exception as err:
            print(f'远程目录{remote_dir}不存在,继续...,具体错误描述为:{err}')
            return
        os.makedirs(local_dir, exist_ok=True)
        remote_dirs = []
        self.ftp.dir(".", remote_dirs.append)
        remote_list = list(map(lambda x: x.split()[-1], remote_dirs))
        print(f'远程目录列表: {remote_list}')
        for remote_detail in remote_dirs:
            file_type = remote_detail[0]
            file_name = remote_detail.split()[-1]
            local_path = os.path.join(local_dir, file_name)
            if file_type == "d":
                self.download_dir(file_name, local_path)
            elif file_type == '-':
                self.download_file(file_name, local_path)
        self.ftp.cwd("..")
        print("返回上层目录: ", self.ftp.pwd())

    def upload_file(self, local_file, remote_file):
        # 上传文件
        remote_file = remote_file if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_file
        print(f"上传文件: {local_file} ---> {remote_file}")
        if not os.path.isfile(local_file):
            print(f'{local_file} 不存在')
            return
        if self.is_same_size(local_file, remote_file):
            print('文件大小相同,此文件跳过')
            return
        try:
            buf_size = 1024
            file_handler = open(local_file, 'rb')
            self.ftp.storbinary(f'STOR {remote_file}', file_handler, buf_size)
            file_handler.close()
        except Exception as err:
            print(f'上传文件出错,出现异常:{err}')

    def upload_dir(self, local_dir, remote_dir):
        # 上传目录
        remote_dir = remote_dir if self.ftp.pwd() == "/" else self.ftp.pwd() + "/" + remote_dir
        print(f"上传目录: {local_dir} ---> {remote_dir}")
        if not os.path.isdir(local_dir):
            print(f'本地目录 {local_dir} 不存在')
            return
        try:
            self.ftp.mkd(remote_dir)
        except Exception as err:
            print(f"创建远程目录{remote_dir}失败,错误描述为:{err}")
            return
        self.ftp.cwd(remote_dir)
        print('切换至远程目录: ', self.ftp.pwd())
        local_name_list = os.listdir(local_dir)
        print("本地目录列表: ", local_name_list)
        for local_name in local_name_list:
            local_name_path = os.path.join(local_dir, local_name)
            if os.path.isdir(local_name_path):
                self.upload_dir(local_name_path, local_name)
            else:
                self.upload_file(local_name_path, local_name)
        self.ftp.cwd("..")
        print("返回上层目录: ", self.ftp.pwd())

sftp

#!/usr/bin/python
# coding=utf-8
import paramiko
import os
import stat


class MySftp:
    def __init__(self, host=None, port=22, username=None, password=None):
        self.sftp_connect = paramiko.Transport((host, port))
        self.sftp_connect.connect(username=username, password=password)
        self.sftp = paramiko.SFTPClient.from_transport(self.sftp_connect)
        print('成功连接到:', host, "登录成功...")

    def __del__(self):
        print("关闭连接")
        self.sftp_connect.close()

    def is_same_size(self, local_file, remote_file):
        # 判断文件大小是否相等
        try:
            remote_file_size = self.sftp.stat(remote_file).st_size
        except Exception as err:
            # print("is_same_size() 错误描述为:%s" % err)
            remote_file_size = -1
        try:
            local_file_size = os.path.getsize(local_file)
        except Exception as err:
            # print("is_same_size() 错误描述为:%s" % err)
            local_file_size = -1
        # print(f'local_file_size:{local_file_size}, remote_file_size:{remote_file_size}')
        if remote_file_size == local_file_size:
            return 1
        else:
            return 0

    def download_file(self, remote_file, local_file):
        remote_file = self.sftp.getcwd() + "/" + remote_file if self.sftp.getcwd() else remote_file
        print(f"下载文件:{remote_file} ---> {local_file}")
        if self.is_same_size(local_file, remote_file):
            print("文件已存在且文件已存在且文件大小相同,此文件跳过")
            return
        try:
            self.sftp.get(remote_file, local_file)
        except Exception as err:
            print(f'下载文件出错,出现异常:{err}')

    def download_dir(self, remote_dir, local_dir):
        remote_dir = self.sftp.getcwd() + "/" + remote_dir if self.sftp.getcwd() else remote_dir
        print(f"下载目录: {remote_dir} ---> {local_dir}")
        try:
            self.sftp.chdir(remote_dir)
            print(f'切换至目录: {self.sftp.getcwd()}')
        except Exception as err:
            print(f'远程目录{remote_dir}不存在,继续...,具体错误描述为:{err}')
            return
        os.makedirs(local_dir, exist_ok=True)
        remote_dirs = self.sftp.listdir(remote_dir)
        print(f'远程目录列表: {remote_dirs}')
        for remote_path in remote_dirs:
            local_path = os.path.join(local_dir, remote_path)
            if str(self.sftp.stat(remote_path))[0] == "d":
                self.download_dir(remote_path, local_path)
            elif str(self.sftp.stat(remote_path))[0] == "-":
                self.download_file(remote_path, local_path)
        self.sftp.chdir("..")
        print("返回上层目录: ", self.sftp.getcwd())
    
    def upload_file(self, local_file, remote_file):
        remote_file = self.sftp.getcwd() + "/" + remote_file if self.sftp.getcwd() else remote_file
        print(f"上传文件: {local_file} ---> {remote_file}")
        if not os.path.isfile(local_file):
            print(f"本地文件 {local_file} 不存在")
            return
        if self.is_same_size(local_file, remote_file):
            print('文件已存在且文件大小相同,此文件跳过')
            return
        try:
            self.sftp.put(local_file, remote_file)
        except Exception as err:
            print(f'上传文件出错,出现异常:{err}') 

    def upload_dir(self, local_dir, remote_dir):
        remote_dir = self.sftp.getcwd() + "/" + remote_dir if self.sftp.getcwd() else remote_dir
        print(f"上传目录: {local_dir} ---> {remote_dir}")
        if not os.path.isdir(local_dir):
            print(f'本地目录 {local_dir} 不存在')
            return
        if not self.is_sftp_dir(remote_dir):
            self.sftp.mkdir(remote_dir)
        self.sftp.chdir(remote_dir)
        print('切换至远程目录: ', self.sftp.getcwd())
        local_name_list = os.listdir(local_dir)
        print("本地目录列表: ", local_name_list)
        for local_name in local_name_list:
            local_name_path = os.path.join(local_dir, local_name)
            if os.path.isdir(local_name_path):
                self.upload_dir(local_name_path, local_name)
            else:
                self.upload_file(local_name_path, local_name)
        self.sftp.chdir("..")
        print("返回上层目录: ", self.sftp.getcwd())

    def is_sftp_dir(self, remote_dir):
        try:
            if stat.S_ISDIR(self.sftp.stat(remote_dir).st_mode):  # 如果remote_dir存在且为目录,则返回True
                return True
        except:
            return False

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值