欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  后端开发

php python ftp操作类

程序员文章站 2022-04-17 09:36:34
...
php python ftp操作类
  1. class Ftp {
  2. //FTP 连接资源
  3. private $link;
  4. //FTP连接时间
  5. public $link_time;
  6. //错误代码
  7. private $err_code = 0;
  8. //传送模式{文本模式:FTP_ASCII, 二进制模式:FTP_BINARY}
  9. public $mode = FTP_BINARY;
  10. /**
  11. 初始化类
  12. **/
  13. public function start($data)
  14. {
  15. if(empty($data['port'])) $data['port'] ='21';
  16. if(empty($data['pasv'])) $data['pasv'] =false;
  17. if(empty($data['ssl'])) $data['ssl'] = false;
  18. if(empty($data['timeout'])) $data['timeout'] = 30;
  19. return $this->connect($data['server'],$data['username'],$data['password'],$data['port'],$data['pasv'],$data['ssl'],$data['timeout']);
  20. }
  21. /**
  22. * 连接FTP服务器
  23. * @param string $host    服务器地址
  24. * @param string $username   用户名
  25. * @param string $password   密码
  26. * @param integer $port     服务器端口,默认值为21
  27. * @param boolean $pasv 是否开启被动模式
  28. * @param boolean $ssl      是否使用SSL连接
  29. * @param integer $timeout 超时时间 
  30. */
  31. public function connect($host, $username = '', $password = '', $port = '21', $pasv = false, $ssl = false, $timeout = 30) {
  32. $start = time();
  33. if ($ssl) {
  34. if (!$this->link = @ftp_ssl_connect($host, $port, $timeout)) {
  35. $this->err_code = 1;
  36. return false;
  37. }
  38. } else {
  39. if (!$this->link = @ftp_connect($host, $port, $timeout)) {
  40. $this->err_code = 1;
  41. return false;
  42. }
  43. }
  44. if (@ftp_login($this->link, $username, $password)) {
  45. if ($pasv)
  46. ftp_pasv($this->link, true);
  47. $this->link_time = time() - $start;
  48. return true;
  49. } else {
  50. $this->err_code = 1;
  51. return false;
  52. }
  53. register_shutdown_function(array(&$this, 'close'));
  54. }
  55. /**
  56. * 创建文件夹
  57. * @param string $dirname 目录名,
  58. */
  59. public function mkdir($dirname) {
  60. if (!$this->link) {
  61. $this->err_code = 2;
  62. return false;
  63. }
  64. $dirname = $this->ck_dirname($dirname);
  65. $nowdir = '/';
  66. foreach ($dirname as $v) {
  67. if ($v && !$this->chdir($nowdir . $v)) {
  68. if ($nowdir)
  69. $this->chdir($nowdir);
  70. @ftp_mkdir($this->link, $v);
  71. }
  72. if ($v)
  73. $nowdir .= $v . '/';
  74. }
  75. return true;
  76. }
  77. /**
  78. * 上传文件
  79. * @param string $remote 远程存放地址
  80. * @param string $local 本地存放地址
  81. */
  82. public function put($remote, $local) {
  83. if (!$this->link) {
  84. $this->err_code = 2;
  85. return false;
  86. }
  87. $dirname = pathinfo($remote, PATHINFO_DIRNAME);
  88. if (!$this->chdir($dirname)) {
  89. $this->mkdir($dirname);
  90. }
  91. if (@ftp_put($this->link, $remote, $local, $this->mode)) {
  92. return true;
  93. } else {
  94. $this->err_code = 7;
  95. return false;
  96. }
  97. }
  98. /**
  99. * 删除文件夹
  100. * @param string $dirname 目录地址
  101. * @param boolean $enforce 强制删除
  102. */
  103. public function rmdir($dirname, $enforce = false) {
  104. if (!$this->link) {
  105. $this->err_code = 2;
  106. return false;
  107. }
  108. $list = $this->nlist($dirname);
  109. if ($list && $enforce) {
  110. $this->chdir($dirname);
  111. foreach ($list as $v) {
  112. $this->f_delete($v);
  113. }
  114. } elseif ($list && !$enforce) {
  115. $this->err_code = 3;
  116. return false;
  117. }
  118. @ftp_rmdir($this->link, $dirname);
  119. return true;
  120. }
  121. /**
  122. * 删除指定文件
  123. * @param string $filename 文件名
  124. */
  125. public function delete($filename) {
  126. if (!$this->link) {
  127. $this->err_code = 2;
  128. return false;
  129. }
  130. if (@ftp_delete($this->link, $filename)) {
  131. return true;
  132. } else {
  133. $this->err_code = 4;
  134. return false;
  135. }
  136. }
  137. /**
  138. * 返回给定目录的文件列表
  139. * @param string $dirname 目录地址
  140. * @return array 文件列表数据
  141. */
  142. public function nlist($dirname) {
  143. if (!$this->link) {
  144. $this->err_code = 2;
  145. return false;
  146. }
  147. if ($list = @ftp_nlist($this->link, $dirname)) {
  148. return $list;
  149. } else {
  150. $this->err_code = 5;
  151. return false;
  152. }
  153. }
  154. /**
  155. * 在 FTP 服务器上改变当前目录
  156. * @param string $dirname 修改服务器上当前目录
  157. */
  158. public function chdir($dirname) {
  159. if (!$this->link) {
  160. $this->err_code = 2;
  161. return false;
  162. }
  163. if (@ftp_chdir($this->link, $dirname)) {
  164. return true;
  165. } else {
  166. $this->err_code = 6;
  167. return false;
  168. }
  169. }
  170. /**
  171. * 获取错误信息
  172. */
  173. public function get_error() {
  174. if (!$this->err_code)
  175. return false;
  176. $err_msg = array(
  177. '1' => 'Server can not connect',
  178. '2' => 'Not connect to server',
  179. '3' => 'Can not delete non-empty folder',
  180. '4' => 'Can not delete file',
  181. '5' => 'Can not get file list',
  182. '6' => 'Can not change the current directory on the server',
  183. '7' => 'Can not upload files'
  184. );
  185. return $err_msg[$this->err_code];
  186. }
  187. /**
  188. * 检测目录名
  189. * @param string $url 目录
  190. * @return 由 / 分开的返回数组
  191. */
  192. private function ck_dirname($url) {
  193. $url = str_replace('', '/', $url);
  194. $urls = explode('/', $url);
  195. return $urls;
  196. }
  197. /**
  198. * 关闭FTP连接
  199. */
  200. public function close() {
  201. return @ftp_close($this->link);
  202. }
  203. }
复制代码
  1. #!/usr/bin/python
  2. #coding=gbk
  3. '''
  4. ftp自动下载、自动上传脚本,可以递归目录操作
  5. '''
  6. from ftplib import FTP
  7. import os,sys,string,datetime,time
  8. import socket
  9. class MYFTP:
  10. def __init__(self, hostaddr, username, password, remotedir, port=21):
  11. self.hostaddr = hostaddr
  12. self.username = username
  13. self.password = password
  14. self.remotedir = remotedir
  15. self.port = port
  16. self.ftp = FTP()
  17. self.file_list = []
  18. # self.ftp.set_debuglevel(2)
  19. def __del__(self):
  20. self.ftp.close()
  21. # self.ftp.set_debuglevel(0)
  22. def login(self):
  23. ftp = self.ftp
  24. try:
  25. timeout = 60
  26. socket.setdefaulttimeout(timeout)
  27. ftp.set_pasv(True)
  28. print '开始连接到 %s' %(self.hostaddr)
  29. ftp.connect(self.hostaddr, self.port)
  30. print '成功连接到 %s' %(self.hostaddr)
  31. print '开始登录到 %s' %(self.hostaddr)
  32. ftp.login(self.username, self.password)
  33. print '成功登录到 %s' %(self.hostaddr)
  34. debug_print(ftp.getwelcome())
  35. except Exception:
  36. deal_error("连接或登录失败")
  37. try:
  38. ftp.cwd(self.remotedir)
  39. except(Exception):
  40. deal_error('切换目录失败')
  41. def is_same_size(self, localfile, remotefile):
  42. try:
  43. remotefile_size = self.ftp.size(remotefile)
  44. except:
  45. remotefile_size = -1
  46. try:
  47. localfile_size = os.path.getsize(localfile)
  48. except:
  49. localfile_size = -1
  50. debug_print('lo:%d re:%d' %(localfile_size, remotefile_size),)
  51. if remotefile_size == localfile_size:
  52. return 1
  53. else:
  54. return 0
  55. def download_file(self, localfile, remotefile):
  56. if self.is_same_size(localfile, remotefile):
  57. debug_print('%s 文件大小相同,无需下载' %localfile)
  58. return
  59. else:
  60. debug_print('>>>>>>>>>>>>下载文件 %s ... ...' %localfile)
  61. #return
  62. file_handler = open(localfile, 'wb')
  63. self.ftp.retrbinary('RETR %s'%(remotefile), file_handler.write)
  64. file_handler.close()
  65. def download_files(self, localdir='./', remotedir='./'):
  66. try:
  67. self.ftp.cwd(remotedir)
  68. except:
  69. debug_print('目录%s不存在,继续...' %remotedir)
  70. return
  71. if not os.path.isdir(localdir):
  72. os.makedirs(localdir)
  73. debug_print('切换至目录 %s' %self.ftp.pwd())
  74. self.file_list = []
  75. self.ftp.dir(self.get_file_list)
  76. remotenames = self.file_list
  77. #print(remotenames)
  78. #return
  79. for item in remotenames:
  80. filetype = item[0]
  81. filename = item[1]
  82. local = os.path.join(localdir, filename)
  83. if filetype == 'd':
  84. self.download_files(local, filename)
  85. elif filetype == '-':
  86. self.download_file(local, filename)
  87. self.ftp.cwd('..')
  88. debug_print('返回上层目录 %s' %self.ftp.pwd())
  89. def upload_file(self, localfile, remotefile):
  90. if not os.path.isfile(localfile):
  91. return
  92. if self.is_same_size(localfile, remotefile):
  93. debug_print('跳过[相等]: %s' %localfile)
  94. return
  95. file_handler = open(localfile, 'rb')
  96. self.ftp.storbinary('STOR %s' %remotefile, file_handler)
  97. file_handler.close()
  98. debug_print('已传送: %s' %localfile)
  99. def upload_files(self, localdir='./', remotedir = './'):
  100. if not os.path.isdir(localdir):
  101. return
  102. localnames = os.listdir(localdir)
  103. self.ftp.cwd(remotedir)
  104. for item in localnames:
  105. src = os.path.join(localdir, item)
  106. if os.path.isdir(src):
  107. try:
  108. self.ftp.mkd(item)
  109. except:
  110. debug_print('目录已存在 %s' %item)
  111. self.upload_files(src, item)
  112. else:
  113. self.upload_file(src, item)
  114. self.ftp.cwd('..')
  115. def get_file_list(self, line):
  116. ret_arr = []
  117. file_arr = self.get_filename(line)
  118. if file_arr[1] not in ['.', '..']:
  119. self.file_list.append(file_arr)
  120. def get_filename(self, line):
  121. pos = line.rfind(':')
  122. while(line[pos] != ' '):
  123. pos += 1
  124. while(line[pos] == ' '):
  125. pos += 1
  126. file_arr = [line[0], line[pos:]]
  127. return file_arr
  128. def debug_print(s):
  129. print (s)
  130. def deal_error(e):
  131. timenow = time.localtime()
  132. datenow = time.strftime('%Y-%m-%d', timenow)
  133. logstr = '%s 发生错误: %s' %(datenow, e)
  134. debug_print(logstr)
  135. file.write(logstr)
  136. sys.exit()
  137. if __name__ == '__main__':
  138. file = open("log.txt", "a")
  139. timenow = time.localtime()
  140. datenow = time.strftime('%Y-%m-%d', timenow)
  141. logstr = datenow
  142. # 配置如下变量
  143. hostaddr = 'localhost' # ftp地址
  144. username = 'test' # 用户名
  145. password = 'test' # 密码
  146. port = 21 # 端口号
  147. rootdir_local = '.' + os.sep + 'bak/' # 本地目录
  148. rootdir_remote = './' # 远程目录
  149. f = MYFTP(hostaddr, username, password, rootdir_remote, port)
  150. f.login()
  151. f.download_files(rootdir_local, rootdir_remote)
  152. timenow = time.localtime()
  153. datenow = time.strftime('%Y-%m-%d', timenow)
  154. logstr += " - %s 成功执行了备份\n" %datenow
  155. debug_print(logstr)
  156. file.write(logstr)
  157. file.close()
复制代码