《瘋狂講義》之多線程下載文件類

該源碼爲瘋狂講義多線程下載工具類, 可以使用,如果需要正式投產 建議添加相關異常處理. 

from urllib.request import *
import threading


class DownUtil:
    def __init__(self, path, targetfile, thread_num):
        # need down file path
        self.path = path
        # Thread number
        self.thread_num = thread_num
        # save file path
        self.targetfile = targetfile
        # Threads
        self.threads = []
        self.file_size = 0;

    def download(self):
        # create request obj
        req = Request(url=self.path,method='GET')
        req.add_header('Accept','*/*')
        req.add_header('CHarset','UTF-8')
        req.add_header('Connection', 'Keep-Alive')
        # open the source
        f = urlopen(req)
        # get file size
        self.file_size = int(dict(f.headers).get('Content-Length',0))
        f.close()

        # current thread need down file size
        current_part_size =self.file_size // self.thread_num + 1
        for i in range(self.thread_num):
            # record begin down file pos
            start_pos = i* current_part_size
            t = open(self.targetfile, 'wb')
            t.seek(start_pos,0)
            td = DownThread(self.path, start_pos, current_part_size, t)
            self.threads.append(td)
            # start Thread
            td.start()

    def get_complete_rate(self):
        sum_size = 0
        for i in range(self.thread_num):
            sum_size += self.threads[i].length
        return sum_size/self.file_size


class DownThread(threading.Thread):
    def __init__(self, path, start_pos, current_part_size, current_part):
        super().__init__()
        self.path = path
        # current thread down pos
        self.start_pos = start_pos
        # need down file size
        self.current_part_size = current_part_size
        # has downed file length
        self.length =0
        self.current_part = current_part

    def run(self):
        req = Request(url=self.path,method='GET')
        req = Request(url=self.path, method='GET')
        req.add_header('Accept', '*/*')
        req.add_header('CHarset', 'UTF-8')
        req.add_header('Connection', 'Keep-Alive')
        # open the source
        f = urlopen(req)
        # skip pos
        for i in range(self.start_pos):
            f.read(1)

        while self.length < self.current_part_size:
            data = f.read(1024)
            if data is None or len(data) <=0:
                break

            self.current_part.write(data)
            self.length += len(data)

        self.current_part.close()
        f.close()


if __name__ =="__main__":
    urlfile ="http://pic1.win4000.com/wallpaper/b/57e8cefd76fdc.jpg"
    down = DownUtil(urlfile,"a.jpg",3)
    down.download()

    def show_process():
        print('finished %.2f' % down.get_complete_rate())
        global thTimer
        if down.get_complete_rate() < 1 :
            thTimer = threading.Timer(0.1,show_process)
            thTimer.start()


    thTimer = threading.Timer(0.1,show_process)
    thTimer.start()

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章