本文实例讲述了python实现支持目录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): #如果下载到本地当前目录下,并创建目录 #下载初始化:如果给定的本地路径不存在需要创建,同时将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)) #如果本地目录不存在,则创建目录 if not os.path.isdir(local_path): os.makedirs(local_path) #进入ftp目录,开始递归查询 self.conn.cwd(ftp_path) ftp_files = self.con