本文實例講述了python實現(xiàn)支持目錄FTP上傳下載文件的方法。分享給大家供大家參考。具體如下:
該程序支持ftp上傳下載文件和目錄、適用于windows和linux平臺。
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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
|
#!/usr/bin/env python # -*- coding: utf-8 -*- import ftplib import os import sys class FTPSync( object ): conn = ftplib.FTP() def __init__( self ,host,port = 21 ): self .conn.connect(host,port) def login( self ,username,password): self .conn.login(username,password) self .conn.set_pasv( False ) print self .conn.welcome def test( self ,ftp_path): print ftp_path print self ._is_ftp_dir(ftp_path) #print self.conn.nlst(ftp_path) #self.conn.retrlines( 'LIST ./a/b') #ftp_parent_path = os.path.dirname(ftp_path) #ftp_dir_name = os.path.basename(ftp_path) #print ftp_parent_path #print ftp_dir_name def _is_ftp_file( self ,ftp_path): try : if ftp_path in self .conn.nlst(os.path.dirname(ftp_path)): return True else : return False except ftplib.error_perm,e: return False def _ftp_list( self , line): list = line.split( ' ' ) if self .ftp_dir_name = = list [ - 1 ] and list [ 0 ].startswith( 'd' ): self ._is_dir = True def _is_ftp_dir( self ,ftp_path): ftp_path = ftp_path.rstrip( '/' ) ftp_parent_path = os.path.dirname(ftp_path) self .ftp_dir_name = os.path.basename(ftp_path) self ._is_dir = False if ftp_path = = '.' or ftp_path = = './' or ftp_path = = '': self ._is_dir = True else : #this ues callback function ,that will change _is_dir value try : self .conn.retrlines( 'LIST %s' % ftp_parent_path, self ._ftp_list) except ftplib.error_perm,e: return self ._is_dir return self ._is_dir def get_file( self ,ftp_path,local_path = '.' ): ftp_path = ftp_path.rstrip( '/' ) if self ._is_ftp_file(ftp_path): file_name = os.path.basename(ftp_path) #如果本地路徑是目錄,下載文件到該目錄 if os.path.isdir(local_path): file_handler = open (os.path.join(local_path,file_name), 'wb' ) self .conn.retrbinary( "RETR %s" % (ftp_path), file_handler.write) file_handler.close() #如果本地路徑不是目錄,但上層目錄存在,則按照本地路徑的文件名作為下載的文件名稱 elif os.path.isdir(os.path.dirname(local_path)): file_handler = open (local_path, 'wb' ) self .conn.retrbinary( "RETR %s" % (ftp_path), file_handler.write) file_handler.close() #如果本地路徑不是目錄,且上層目錄不存在,則退出 else : print 'EROOR:The dir:%s is not exist' % os.path.dirname(local_path) else : print 'EROOR:The ftp file:%s is not exist' % ftp_path def put_file( self ,local_path,ftp_path = '.' ): ftp_path = ftp_path.rstrip( '/' ) if os.path.isfile( local_path ): file_handler = open (local_path, "r" ) local_file_name = os.path.basename(local_path) #如果遠程路徑是個目錄,則上傳文件到這個目錄,文件名不變 if self ._is_ftp_dir(ftp_path): self .conn.storbinary( 'STOR %s' % os.path.join(ftp_path,local_file_name), file_handler) #如果遠程路徑的上層是個目錄,則上傳文件,文件名按照給定命名 elif self ._is_ftp_dir(os.path.dirname(ftp_path)): print 'STOR %s' % ftp_path self .conn.storbinary( 'STOR %s' % ftp_path, file_handler) #如果遠程路徑不是目錄,且上一層的目錄也不存在,則提示給定遠程路徑錯誤 else : print 'EROOR:The ftp path:%s is error' % ftp_path file_handler.close() else : print 'ERROR:The file:%s is not exist' % local_path def get_dir( self ,ftp_path,local_path = '.' ,begin = True ): ftp_path = ftp_path.rstrip( '/' ) #當ftp目錄存在時下載 if self ._is_ftp_dir(ftp_path): #如果下載到本地當前目錄下,并創(chuàng)建目錄 #下載初始化:如果給定的本地路徑不存在需要創(chuàng)建,同時將ftp的目錄存放在給定的本地目錄下。 #ftp目錄下文件存放的路徑為local_path=local_path+os.path.basename(ftp_path) #例如:將ftp文件夾a下載到本地的a/b目錄下,則ftp的a目錄下的文件將下載到本地的a/b/a目錄下 if begin: if not os.path.isdir(local_path): os.makedirs(local_path) local_path = os.path.join(local_path,os.path.basename(ftp_path)) #如果本地目錄不存在,則創(chuàng)建目錄 if not os.path.isdir(local_path): os.makedirs(local_path) #進入ftp目錄,開始遞歸查詢 self .conn.cwd(ftp_path) ftp_files = self .conn.nlst() for file in ftp_files: local_file = os.path.join(local_path, file ) #如果file ftp路徑是目錄則遞歸上傳目錄(不需要再進行初始化begin的標志修改為False) #如果file ftp路徑是文件則直接上傳文件 if self ._is_ftp_dir( file ): self .get_dir( file ,local_file, False ) else : self .get_file( file ,local_file) #如果當前ftp目錄文件已經遍歷完畢返回上一層目錄 self .conn.cwd( ".." ) return else : print 'ERROR:The dir:%s is not exist' % ftp_path return def put_dir( self ,local_path,ftp_path = '.' ,begin = True ): ftp_path = ftp_path.rstrip( '/' ) #當本地目錄存在時上傳 if os.path.isdir(local_path): #上傳初始化:如果給定的ftp路徑不存在需要創(chuàng)建,同時將本地的目錄存放在給定的ftp目錄下。 #本地目錄下文件存放的路徑為ftp_path=ftp_path+os.path.basename(local_path) #例如:將本地文件夾a上傳到ftp的a/b目錄下,則本地a目錄下的文件將上傳的ftp的a/b/a目錄下 if begin: if not self ._is_ftp_dir(ftp_path): self .conn.mkd(ftp_path) ftp_path = os.path.join(ftp_path,os.path.basename(local_path)) #如果ftp路徑不是目錄,則創(chuàng)建目錄 if not self ._is_ftp_dir(ftp_path): self .conn.mkd(ftp_path) #進入本地目錄,開始遞歸查詢 os.chdir(local_path) local_files = os.listdir( '.' ) for file in local_files: #如果file本地路徑是目錄則遞歸上傳目錄(不需要再進行初始化begin的標志修改為False) #如果file本地路徑是文件則直接上傳文件 if os.path.isdir( file ): ftp_path = os.path.join(ftp_path, file ) self .put_dir( file ,ftp_path, False ) else : self .put_file( file ,ftp_path) #如果當前本地目錄文件已經遍歷完畢返回上一層目錄 os.chdir( ".." ) else : print 'ERROR:The dir:%s is not exist' % local_path return if __name__ = = '__main__' : ftp = FTPSync( '192.168.1.110' ) ftp.login( 'test' , 'test' ) #上傳文件,不重命名 #ftp.put_file('111.txt','a/b') #上傳文件,重命名 #ftp.put_file('111.txt','a/112.txt') #下載文件,不重命名 #ftp.get_file('/a/111.txt',r'D:\\') #下載文件,重命名 #ftp.get_file('/a/111.txt',r'D:\112.txt') #下載到已經存在的文件夾 #ftp.get_dir('a/b/c',r'D:\\a') #下載到不存在的文件夾 #ftp.get_dir('a/b/c',r'D:\\aa') #上傳到已經存在的文件夾 ftp.put_dir( 'b' , 'a' ) #上傳到不存在的文件夾 ftp.put_dir( 'b' , 'aa/B/' ) |
希望本文所述對大家的Python程序設計有所幫助。