 sftp案例
sftp案例
  # 案例
# -*- coding: utf-8 -*-
import traceback
import os
import stat
import logging
import paramiko
class SftpFile(object):
    def __init__(self, ip, port, username, pwd):
        self.ip = ip
        self.port = port
        self.username = username
        self.pwd = pwd
        self.sftp = self.init_sftp()
    def init_sftp(self):
        sf = paramiko.Transport((self.ip, self.port))
        sf.connect(username=self.username, password=self.pwd)
        return paramiko.SFTPClient.from_transport(sf)
    # 判断sftp服务端文件路径是否存在,若不存在则创建
    def create_dir(self, remote_dir):
        try:
            if stat.S_ISDIR(self.sftp.stat(remote_dir).st_mode):  # 如果remote_dir存在且为目录,则忽略
                pass
        except Exception:
            self.make_dirs(remote_dir)
            logging.info("在远程[{}]上创建目录:{}".format(self.ip, remote_dir))
    # 从根目录创建多级文件夹
    def make_dirs(self, remote_dir):
        self.sftp.chdir('/')
        for dir_item in remote_dir.split('/'):
            if not dir_item:
                continue
            try:
                self.sftp.chdir(dir_item)
            except Exception:
                self.sftp.mkdir(dir_item)
                self.sftp.chdir(dir_item)
    def sftp_upload(self, local_dir, remote_dir):
        if os.path.isdir(local_dir):
            self.create_dir(remote_dir)
        elif os.path.isfile(local_dir):
            self.create_dir(os.path.dirname(remote_dir))
        self.upload(local_dir, remote_dir)
    def sftp_upload_list(self, local_files, remote_files):
        for index, value in enumerate(local_files):
            self.sftp_upload(value, remote_files[index])
    # 上传
    def upload(self, local_dir, remote_dir):
        if os.path.isdir(local_dir):  # 判断本地local_dir是否为目录
            for f in os.listdir(remote_dir):
                remote_dir_tmp = os.path.join(remote_dir, f)
                local_dir_tmp = os.path.join(remote_dir, f)
                if os.path.isdir(local_dir_tmp):  # 如果本地local_dir_tmp为目录,则对远程sftp服务器进行判断
                    self.create_dir(remote_dir_tmp)  # 判断sftp服务端文件目录是否存在,若不存在则创建
                self.sftp_upload(local_dir_tmp, remote_dir_tmp)
        else:
            tmp_remote_file = remote_dir + '.tmp'  # 先存为.tmp文件
            try:
                self.sftp.put(local_dir, tmp_remote_file)
                logging.info("upload file success:{}".format(remote_dir))
            except Exception:
                logging.error('upload file fail:{}'.format(remote_dir))
                logging.info(traceback.format_exc())
                raise
            try:
                self.sftp.posix_rename(tmp_remote_file, tmp_remote_file[:-4])  # 重命名
                logging.info("sftp rename success:{} to {}".format(tmp_remote_file, tmp_remote_file[:-4]))
            except Exception:
                logging.error("sftp rename fail:{} to {}".format(tmp_remote_file, tmp_remote_file[:-4]))
                logging.info(traceback.format_exc())
                raise
    def __enter__(self):
        return self
    def __exit__(self, exc_type, exc_val, exc_tb):
        self.sftp.close()
if __name__ == '__main__':
    localDir = 'sftp_file.py'  # 本地文件或目录
    remoteDir = '/data/tmp/sftp_file.py'  # 远程文件或目录(注意远程路径要存在)
    with SftpFile('', 22, '', '') as sf:
        sf.sftp_upload(localDir, remoteDir)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
上次更新: 2023/09/04, 18:39:45
