其实,在一般的文件编程中,这有两个概念要说明:

第一是,下载一个大文件,将这个大文件多为多线程。

第二是,下载N多小文件,将每个线程指定下载多个小文件。

现在实现的是多线程下载一个大文件。

今天完成了一个很有意思的下载图片的功能。想加入多线程功能。

#!/usr/bin/python
# -*- coding: utf-8 -*-
# filename: paxel.py

'''It is a multi-thread downloading tool

    It was developed follow axel.
        Author: volans
        E-mail: volansw [at] gmail.com
'''

import sys
import os
import time
import urllib
from threading import Thread

local_proxies = {'http': 'http://131.139.58.200:8080'}

class AxelPython(Thread, urllib.FancyURLopener):
    '''Multi-thread downloading class.

        run() is a vitural method of Thread.
    '''
    def __init__(self, threadname, url, filename, ranges=0, proxies={}):
        Thread.__init__(self, name=threadname)
        urllib.FancyURLopener.__init__(self, proxies)
        self.name = threadname
        self.url = url
        self.filename = filename
        self.ranges = ranges
        self.downloaded = 0

    def run(self):
        '''vertual function in Thread'''
        try:
            self.downloaded = os.path.getsize( self.filename )
        except OSError:
            #print 'never downloaded'
            self.downloaded = 0

        # rebuild start poind
        self.startpoint = self.ranges[0] + self.downloaded

        # This part is completed
        if self.startpoint >= self.ranges[1]:
            print 'Part %s has been downloaded over.' % self.filename
            return

        self.oneTimeSize = 16384 #16kByte/time
        print 'task %s will download from %d to %d \n' % (self.name, self.startpoint, self.ranges[1])
        self.addheader("Range", "bytes=%d-%d" % (self.startpoint, self.ranges[1]))

        self.urlhandle = self.open( self.url )

        data = self.urlhandle.read( self.oneTimeSize )
        while data:
            filehandle = open( self.filename, 'ab+' )
            filehandle.write( data )
            filehandle.close()

            self.downloaded += len( data )
            #print "%s" % (self.name)
            #progress = u'\r...'

            data = self.urlhandle.read( self.oneTimeSize )

def GetUrlFileSize(url, proxies={}):
    urlHandler = urllib.urlopen( url, proxies=proxies )
    headers = urlHandler.info().headers
    length = 0
    for header in headers:
        if header.find('Length') != -1:
            length = header.split(':')[-1].strip()
            length = int(length)
    return length

def SpliteBlocks(totalsize, blocknumber):
    blocksize = totalsize/blocknumber
    ranges = []
    for i in range(0, blocknumber-1):
        ranges.append((i*blocksize, i*blocksize +blocksize - 1))
    ranges.append(( blocksize*(blocknumber-1), totalsize -1 ))

    return ranges
def islive(tasks):
    for task in tasks:
        if task.isAlive():
            return True
    return False

def paxel(url, output, blocks=6, proxies=local_proxies):
    ''' paxel
    '''
    size = GetUrlFileSize( url, proxies )
    ranges = SpliteBlocks( size, blocks )

    threadname = [ "thread_%d" % i for i in range(0, blocks) ]
    filename = [ "tmpfile_%d" % i for i in range(0, blocks) ]

    tasks = []
    for i in range(0,blocks):
        task = AxelPython( threadname[i], url, filename[i], ranges[i] )
        task.setDaemon( True )
        task.start()
        tasks.append( task )

    time.sleep( 2 )
    while islive(tasks):
        downloaded = sum( [task.downloaded for task in tasks] )
        process = downloaded/float(size)*100
        show = u'\rFilesize:%d Downloaded:%d Completed:%.2f%%' % (size, downloaded, process)
        sys.stdout.write(show)
        sys.stdout.flush()
        time.sleep( 0.1 )
        print

    filehandle = open( output, 'wb+' )
    for i in filename:
        f = open( i, 'rb' )
        filehandle.write( f.read() )
        f.close()
        try:
            os.remove(i)
            pass
        except:
            pass

    filehandle.close()

if __name__ == '__main__':
    url = "http://6.duote.com.cn/geany_setup.zip"
    output = 'geany_setup.zip'
    paxel( url, output, blocks=5, proxies={} )

PYTHON文件多线程下载的更多相关文章

  1. python文件管道 下载图集

    # -*- coding: utf-8 -*- import re from time import sleep import scrapy from scrapy.linkextractors im ...

  2. Python实现多线程下载

    #!/usr/bin/python # -*- coding: utf-8 -*- # filename: paxel.py '''It is a multi-thread downloading t ...

  3. android 学习随笔十三(网络:多线程下载)

    多线程断点续传下载1.多线程:快* 原理:抢占服务器资源* 单线程下载:线程从第0个字节开始下,下到最后一个字节,在本地硬盘的临时文件中从第0个字节开始写,写到最后一个字节,下载完成时,临时文件也写完 ...

  4. [iOS 多线程 & 网络 - 2.4] - 大文件下载 (边下边写/暂停恢复下载/压缩解压zip/多线程下载)

    A.需求 边下边写入硬盘 显示下载进度 暂停/恢复 下载 解压文件 多线程下载   B.基本知识 1.小文件下载 如果文件比较小,下载方式会比较多直接用NSData的+ (id)dataWithCon ...

  5. Android中多线程下载列表的封装实现(含进度反馈)

    来源:http://blog.csdn.net/u011638883/article/details/17347015 实现了一下Android中的文件多线程下载模块,支持自定义线程数.断点续传.下载 ...

  6. Python之FTP多线程下载文件之分块多线程文件合并

    Python之FTP多线程下载文件之分块多线程文件合并 欢迎大家阅读Python之FTP多线程下载系列之二:Python之FTP多线程下载文件之分块多线程文件合并,本系列的第一篇:Python之FTP ...

  7. Python之FTP多线程下载文件之多线程分块下载文件

    Python之FTP多线程下载文件之多线程分块下载文件 Python中的ftplib模块用于对FTP的相关操作,常见的如下载,上传等.使用python从FTP下载较大的文件时,往往比较耗时,如何提高从 ...

  8. python线程使用场景 多线程下载

    http://blog.xiayf.cn/2015/09/11/parallelism-in-one-line http://python.jobbole.com/84327/ http://www. ...

  9. Python实现多线程HTTP下载器

    本文将介绍使用Python编写多线程HTTP下载器,并生成.exe可执行文件. 环境:windows/Linux + Python2.7.x 单线程 在介绍多线程之前首先介绍单线程.编写单线程的思路为 ...

随机推荐

  1. pip常用命令

    以flask为例. 1. 安装 # pip install flask 安装 flask. # pip install flask==1.0 安装 1.0版本的flask # pip install ...

  2. 黑马程序员_<<properties,打印流,合并流,分割流>>

    --------------------ASP.Net+Android+IOS开发..Net培训.期待与您交流! -------------------- 1. Properties 1.概述 Pro ...

  3. Git Bash 使用心得

    1:下载Git  Git for Windows 2:点击安装,依次默认下一步 3:安装完成 4:设置SSH建立计算机与Github的链接 4.1 点击开始菜单找到Git Bash,并点击: 4.2 ...

  4. "解密"微信开放高级接口 企业如何应对

    今天(2013年10月29日)腾讯终于对外公开了微信公众平台最新的接口,一石激起千层浪,对于很多微信公众平台的运营人员来说,今天是令人兴奋的一天!微信在向申请服务号的企业开发了大量接口.用户不想输入文 ...

  5. 一分钟明确 VS manifest 原理

    什么是vs 程序的manifest文件 manifest 是VS程序用来标明所依赖的side-by-side组建,如ATL, CRT等的清单. 为什么要有manifest文件 一台pc上,用一组建往往 ...

  6. POJ 3233 Matrix Power Series (矩阵+二分+二分)

    题目地址:http://poj.org/problem?id=3233 题意:给你一个矩阵A,让你求A+A^2+……+A^k模p的矩阵值 题解:我们知道求A^n我们可以用二分-矩阵快速幂来求,而 当k ...

  7. 使用单例模式实现自己的HttpClient工具类

    引子 在Android开发中我们经常会用到网络连接功能与服务器进行数据的交互,为此Android的SDK提供了Apache的HttpClient 来方便我们使用各种Http服务.你可以把HttpCli ...

  8. Maven实战——生命周期和插件

    Maven的构建过程包含:初始化.编译.測试.打包.集成測试.部署 Maven拥有三套相互独立的生命周期:clean(清理项目).default(构建项目).site(建立项目网站) 每一个生命周期包 ...

  9. ERROR<53761> - Plugins - conn=-1 op=-1 msgId=-1 - Connection Bind through PTA failed (91). Retrying...

    LDAP6.3在DSCC控制台启动实例完成,但是操作状态显示“意外错误”,查看日志如下: 04/May/2016:21:10:39 +0800] - Sun-Java(tm)-System-Direc ...

  10. Apache和Nginx平滑重启

    之前修改了服务器配置都是简单粗暴的用restart重启apache/nginx,据说这样不好.需要平滑重启服务器,避免重启时打断用户行为.然后就根据官方文档了解了一下平滑重启的命令.本文根据Apach ...