设为首页 收藏本站
查看: 6952|回复: 0

[经验分享] Python之FTP多线程下载文件之多线程分块下载文件

[复制链接]

尚未签到

发表于 2015-4-23 10:42:23 | 显示全部楼层 |阅读模式
  Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等。使用python从FTP下载较大的文件时,往往比较耗时,如何提高从FTP下载文件的速度呢?多线程粉墨登场,本文给大家分享我的多线程下载代码,需要用到的python主要模块包括:ftplib和threading。
  首先讨论我们的下载思路,示意如下:
DSC0000.png
  1. 将文件分块,比如我们打算采用20个线程去下载同一个文件,则需要将文件以二进制方式打开,平均分成20块,然后分别启用一个线程去下载一个块:



1 def setupThreads(self, filePath, localFilePath, threadNumber = 20):
2     """
3     set up the threads which will be used to download images
4     list of threads will be returned if success, else
5     None will be returned
6     """
7     try:
8         temp = self.ftp.sendcmd('SIZE ' + filePath)
9         remoteFileSize = int(string.split(temp)[1])
10         blockSize = remoteFileSize / threadNumber
11         rest = None
12         threads = []
13         for i in range(0, threadNumber - 1):
14             beginPoint = blockSize * i
15             subThread = threading.Thread(target = self.downloadFileMultiThreads, args = (i, filePath, localFilePath, beginPoint, blockSize, rest,))
16             threads.append(subThread)
17            
18         assigned = blockSize * threadNumber
19         unassigned = remoteFileSize - assigned
20         lastBlockSize = blockSize + unassigned
21         beginPoint = blockSize * (threadNumber - 1)
22         subThread = threading.Thread(target = self.downloadFileMultiThreads, args = (threadNumber - 1, filePath, localFilePath, beginPoint, lastBlockSize, rest,))
23         threads.append(subThread)
24         return threads
25     except Exception, diag:
26         self.recordLog(str(diag), 'error')
27         return None
  其中的downloadFileMultiThreads函数如下:



1 def downloadFileMultiThreads(self, threadIndex, remoteFilePath, localFilePath, \
2                                  beginPoint, blockSize, rest = None):
3     """
4     A sub thread used to download file
5     """
6     try:
7         threadName = threading.currentThread().getName()
8         # temp local file
9         fp = open(localFilePath + '.part.' + str(threadIndex), 'wb')
10         callback = fp.write
11         
12         # another connection to ftp server, change to path, and set binary mode
13         myFtp = FTP(self.host, self.user, self.passwd)
14         myFtp.cwd(os.path.dirname(remoteFilePath))
15         myFtp.voidcmd('TYPE I')
16         
17         finishedSize = 0
18         # where to begin downloading
19         setBeginPoint = 'REST ' + str(beginPoint)
20         myFtp.sendcmd(setBeginPoint)
21         # begin to download
22         beginToDownload = 'RETR ' + os.path.basename(remoteFilePath)
23         connection = myFtp.transfercmd(beginToDownload, rest)
24         readSize = self.fixBlockSize
25         while 1:
26             if blockSize > 0:
27                 remainedSize = blockSize - finishedSize
28                 if remainedSize > self.fixBlockSize:
29                     readSize = self.fixBlockSize
30                 else:
31                     readSize = remainedSize
32             data = connection.recv(readSize)
33             if not data:
34                 break
35             finishedSize = finishedSize + len(data)
36             # make sure the finished data no more than blockSize
37             if finishedSize == blockSize:
38                 callback(data)
39                 break
40             callback(data)
41         connection.close()
42         fp.close()
43         myFtp.quit()
44         return True
45     except Exception, diag:
46         return False
  2. 等待下载完成之后我们需要对各个文件块进行合并,合并的过程见本系列之二:Python之FTP多线程下载文件之分块多线程文件合并
  
  感谢大家的阅读,希望能够帮到大家!
  Published by Windows Live Writer!

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-59974-1-1.html 上篇帖子: python 静态成员变量 下篇帖子: Python登录人人网并抓取新鲜事
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表