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 download(url, target=os.getcwd(), blocks=6, proxies=local_proxies):
flag=True
print('Retrieving resource information...')
url=urllib.parse.quote(url,safe='/%&@=+?$;,:') #将提供的url编码,非英文字符将被编码为标准格式
try:
infos=GetUrlFileInfo(url,proxies) #获取文件信息
except Exception as ex:
print(ex)
flag=False
if flag:
if not os.path.exists(target):
os.makedirs(target)
size=infos[2] #获取到的文件大小
output=os.path.join(target,''.join(infos[0])) #根据获取到的文件名和指定的保存目录生成完整路径
type=infos[1][0]
starttime=time.time() #开始计时
print('Infomation:')
print('FileName:{0} FileType:{1} FileLength:{2}'.format(''.join(infos[0]),'/'.join(infos[1]),infos[2] if int(infos[2]) > 0 else 'Unknown')) #打印获取到的文件信息
if size > 0: #size大于0表示成功获取文件长度,可以进行多线程下载
print('Starting multithread download...')
ranges = SpliteBlocks( size, blocks )
else: #只能单线程下载,线程数置1,ranges置空,
print('Starting single thread download...')
ranges=()
blocks=1
threadname = [ infos[0][0]+"_thread_%d" % i for i in range(0, blocks) ] #生成线程名
filename = [ infos[0][0]+ "_tmpfile_%d" % i for i in range(0, blocks) ] #生成各线程的临时文件名
tasks = []
for i in range(0,blocks): #生成下载线程,设置为后台线程后启动,将线程加入到线程列表中
task = Maple( threadname[i], url, filename[i], ranges[i] if ranges else ranges,proxies)
task.setDaemon( True )
task.start()
tasks.append( task )