`
xiaobian
  • 浏览: 589167 次
  • 来自: 北京
社区版块
存档分类
最新评论

多线程下载文件

阅读更多
#!/usr/bin/python
#coding=gbk

import re
import os
import sys
import time
import glob
import string
import socket
import getopt
import urllib
import urllib2
import threading
from sgmllib import SGMLParser

#############################################################################
#
# self-defined exception classes
#
#############################################################################
class ConnectionError(Exception): pass
class URLUnreachable(Exception):pass
class CanotDownload(Exception):pass

#############################################################################
#
# multiple threads download module starts here
#
#############################################################################
class HttpGetThread(threading.Thread):
    def __init__(self, name, url, filename, range=0):
        #print " name ",name
        #print " url ",url
        #print " filename ",filename 
        #print " range ",range
        threading.Thread.__init__(self, name=name)
        self.url = url
        self.filename = filename
        self.range = range
        self.totalLength = range[1] - range[0] +1
        try:
            self.downloaded = os.path.getsize(self.filename)
        except OSError:
            self.downloaded = 0
        self.percent = self.downloaded/float(self.totalLength)*100
        self.headerrange = (self.range[0]+self.downloaded, self.range[1])
        self.bufferSize = 8192


    def run(self):
        try:
            self.downloaded = os.path.getsize(self.filename)
        except OSError:
            self.downloaded = 0
        self.percent = self.downloaded/float(self.totalLength)*100
        #self.headerrange = (self.range[0]+self.downloaded, self.range[1])
        self.bufferSize = 8192
        #request = urllib2.Request(self.url)
        #request.add_header('Range', 'bytes=%d-%d' %self.headerrange)
        downloadAll = False
        retries = 1
        while not downloadAll:
            if retries > 10:
                break
            try: 
                self.headerrange = (self.range[0]+self.downloaded, self.range[1])
                request = urllib2.Request(self.url)
                request.add_header('Range', 'bytes=%d-%d' %self.headerrange)
                conn = urllib2.urlopen(request)
                startTime = time.time()
                data = conn.read(self.bufferSize)
                while data:
                    f = open(self.filename, 'ab')
                    f.write(data)
                    f.close()
                    self.time = int(time.time() - startTime)
                    self.downloaded += len(data)
                    self.percent = self.downloaded/float(self.totalLength) *100               
                    data = conn.read(self.bufferSize)
                downloadAll = True
            except Exception, err:
                retries += 1
                time.sleep(1)
                continue

#分割文件方便多线程下载
def Split(size,blocks):
  
    ranges = []
    blocksize = size / blocks
    for i in xrange(blocks-1):
        ranges.append((i*blocksize,blocksize*i+blocksize-1))
    ranges.append(( blocksize*(blocks-1), size-1))
    #print ranges
    return ranges
#获得文件大小
def GetHttpFileSize(url):
    length = 0
    try:
        conn = urllib.urlopen(url)
        headers = conn.info().headers
        for header in headers:
            if header.find('Length') != -1:
                length = header.split(':')[-1].strip()
                length = int(length)
    except Exception, err:
        pass
        
    return length

def hasLive(ts):
    for t in ts:
        print "\n thread name ",t.getName()," alive ",t.isAlive()
        if t.isAlive():
            return True
    return False
#
def MyHttpGet(url, output=None, connections=4):
    """
    arguments:
        url, in GBK encoding
        output, default encoding, do no convertion
        connections, integer
    """
    
    length = GetHttpFileSize(url)
    startTime = time.time() #开始时间
    #print " startTime ",startTime
    mb = length/1024/1024.0
    if length == 0:
        raise URLUnreachable
    blocks = connections
    if output:
        filename = output
    else:
        output = url.split('/')[-1]
    ranges = Split(length, blocks)
    names = []
    #names = ["%s_%d" %(filename,i) for i in xrange(blocks)]
    for i in xrange(blocks):
        names.append("%s_%d" %(filename,i))
    ts = []
    #print "+++++++++++++++++++++++++++ blocks ",blocks
    for i in xrange(blocks):
        t = HttpGetThread(" 下载线程 "+str(i), url, names[i], ranges[i])
        t.setDaemon(True)
        t.start()
        ts.append(t)

    live = hasLive(ts)
    startSize = sum([t.downloaded for t in ts]) # 已下载多少
    #print "++++++++++ startSize ",startSize
   
    etime = 0 #
    rate = 0 # 下载速度 *
    while live:
        try:
            etime = time.time() - startTime
            d = sum([t.downloaded for t in ts])/float(length)*100
            downloadedThistime = sum([t.downloaded for t in ts])-startSize
            try:
                rate = downloadedThistime / float(etime)/1024
            except:
                rate = 0.0
            progressStr = u'\rFilesize: %d(%.2fM)  Downloaded: %.2f%%  Avg rate: %.1fKB/s' %(length, mb, d, rate)
            sys.stdout.write(progressStr)
            sys.stdout.flush()
            #sys.stdout.write('\b'*(len(progressStr)+1))
            live = hasLive(ts)
            time.sleep(0.8)
        except KeyboardInterrupt:
            print
            print "Exit..."
            for n in names:
                try:
                    os.remove(n)
                except:
                    pass
            sys.exit(1)
            
    print
    etime = time.time() - startTime
    print " endTime ",time.time()
    print  u'耗时: %d:%d, 平均速度:%.2fKB/s' %(int(etime)/60, int(etime)%60,rate) 

    f = open(filename, 'wb')
    for n in names:
        f.write(open(n,'rb').read())
        try:
            os.remove(n)
        except:
            pass
    f.close()

if __name__ == "__main__":
    url = "http://www.jszg.com.cn/webpage/网页作业/天黑黑.mp3"
    output = "孙燕姿---天黑黑.mp3"
    connections = 10
    MyHttpGet(url,output,connections);
 
分享到:
评论

相关推荐

    C#实现多线程下载文件

    通过上述步骤,我们可以实现一个高效的多线程文件下载器。这个过程涉及到的知识点包括:线程与线程池、异步编程、文件I/O、HTTP范围请求、异常处理和进度更新。这些知识对于任何希望深入理解C#并发编程和网络编程的...

    SpringBoot版本的多线程下载文件,分段下载文件

    首先,多线程下载文件是一种提高下载速度的方法,通过将大文件分成多个小部分,每个部分由一个单独的线程负责下载,从而充分利用多核处理器的并行处理能力。在Java中,我们可以使用`java.util.concurrent`包中的`...

    android多线程下载文件

    在Android开发中,多线程下载文件是一种常见的优化策略,特别是在处理大文件或者网络环境不稳定的情况下,能够提高下载效率并减少资源浪费。本项目提供的就是一个实现了多线程断点续传功能的Android下载器,它包含...

    java实现多线程下载文件

    通过以上步骤,我们可以设计并实现一个高效的多线程文件下载系统。在实际项目中,还可以考虑使用成熟的库,如Apache HttpClient或OkHttp,它们提供了对多线程下载的良好支持。同时,结合Java的并发库,可以构建出更...

    Android多线程下载文件

    在Android应用开发中,多线程下载文件是一个常见的需求,特别是在处理大文件或者需要优化用户体验时。这个场景中,我们采用多线程技术来提高下载效率,并且支持断点续传功能,这意味着如果下载过程中因网络问题中断...

    可以多线程下载文件的c++客户端

    可以多线程下载文件c++的客户端软件,可以切割文件并传输

    C#多线程下载文件源码

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如文件下载时。本文将深入探讨如何使用C#实现多线程下载文件,并基于提供的源码进行分析和学习。 首先,多线程的概念是并发执行多个...

    C# 多线程下载文件

    在C#编程中,多线程技术是一种提升应用程序性能的有效方式,特别是在处理耗时操作如大文件下载时。本文将深入探讨如何利用C#实现多线程下载文件,并结合给出的"多线程下载文件"项目,理解其工作原理。 首先,让我们...

    多线程分别下载文件

    这个"多线程分别下载文件"的Demo是针对在ListView或GridView控件中实现的一项功能,允许用户选择多个文件进行并行下载,并且每个文件的下载进度可以在对应的列表项中实时更新,提供良好的用户体验。 首先,我们要...

    Android多线程下载文件实例

    在Android应用开发中,多线程技术是必不可少的,特别是在处理耗时操作,如网络请求、文件下载等场景。本文将深入探讨如何在Android中实现多线程下载文件的实例。 首先,我们要理解多线程的基本概念。在单线程环境中...

    qt多线程高效下载文件

    本项目"qt多线程高效下载文件"是基于Qt实现的一个实用工具,它利用多线程技术来提高文件下载的效率,特别是对于大文件或者需要同时下载多个文件的场景,这种多线程策略显得尤为重要。 在HTTP协议方面,它是互联网上...

    java多线程下载文件

    ### Java多线程断点下载文件:关键技术与实现 在当今高速互联网环境下,高效的数据传输技术变得至关重要。Java多线程断点续传文件下载技术就是一种能够显著提高下载速度和稳定性的方法。本文将深入解析Java多线程...

    关于vb多线程下载文件的例子

    下面我们将详细讲解如何使用VB创建一个简单的多线程文件下载程序。 首先,我们需要创建一个新的线程来执行下载任务。在VB中,我们可以创建一个`Thread`对象,并为其传递一个委托(Delegate),这个委托指向要在线程...

    delphi7多线程下载文件

    在Delphi7中,开发多线程下载文件的应用程序是一项技术含量较高的任务,涉及到并发处理、网络通信以及文件I/O等多个方面。在这个场景下,我们通常会利用Indy10库,尤其是其中的IdHTTP组件来实现网络请求,再结合多...

    htp多线程断点下载文件

    在IT领域,网络数据传输是不可或缺的一部分,而断点续传和多线程下载技术则大大提升了文件下载的效率和用户体验。"htp多线程断点下载文件"这一主题,涉及了网络编程、多线程技术和文件处理等多个知识点。 首先,...

    多线程实现文件下载,代码规范明了

    在多线程文件下载中,我们可以为每个线程创建一个Socket,分别与服务器保持连接,实现文件的分块下载。 2. HTTP:超文本传输协议是互联网上应用最广泛的一种网络协议。HTTP支持断点续传功能,非常适合大文件的下载...

    java多线程下载文件源码

    在Java编程中,多线程下载文件是一种优化大文件下载效率的技术。它通过将一个大文件分割成多个小部分,然后在不同的线程中并行下载这些部分,从而充分利用网络带宽,加快下载速度。本源码实现了这样一个功能,让下载...

    Python3中的单线程带进度条和多线程下载文件代码及注意事项

    写一个多线程分块下载文件工具。网上的一些代码可能会有些奇怪的问题,用的是类全局变量打开文件但在多线程中并未加锁,会导致文件有一定几率出现大小和源文件不同,即使文件大小相同,MD5值也不同,中间有一段是坏的...

    C# Winform 多线程下载

    在C# Winform应用中实现多线程下载是一项常见的任务,尤其在处理大文件或需要提高下载速度的情况下。本文将详细讲解如何利用C#的多线程技术来创建一个Winform应用程序,实现高效的文件下载功能。 首先,我们需要...

Global site tag (gtag.js) - Google Analytics