|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
写个一个多线程下载,
但是无法暂停跟恢复,
老哥们帮忙处理下这个问题。
import json
import os
import requests
import threading
import tkinter as tk
from tkinter import filedialog,messagebox
from concurrent.futures import ThreadPoolExecutor
import logging
# 创建日志目录
# os.makedirs('logs', exist_ok=True)
# logging.basicConfig(filename='logs/download.log', level=logging.ERROR)
# BASE_DIR = 'BASE_DIR' # 下载文件的基本目录,你需要根据需要进行修改
# 定义下载函数
def download_file(download_url, directory, lock, event, label, count):
try:
# 获取下载文件的文件名
filename = os.path.basename(download_url)
print('正在下载文件:', filename )
base_url = url_entry.get()
# 创建目录
os.makedirs(directory, exist_ok=True)
# 下载文件
response = requests.get(base_url+"/webres/"+download_url, timeout=10)
with lock:
with open(os.path.join(directory, filename), 'wb') as f:
f.write(response.content)
print(f'文件 {download_url} 下载结束')
label.set(f'正在下载文件:{filename}+下载文件数量:{count}') # 更新窗口中的标签
except Exception as e:
print(f'下载文件 {base_url+download_url} 出错: {e}')
logging.error(f'下载文件 {download_url} 出错')
finally:
event.set() # 下载结束后设置 event
# 定义选择文件函数
def choose_file():
file_path = filedialog.askopenfilename()
file_path_var.set(file_path)
# 读取本地json文件
with open(file_path, 'r') as f:
data = json.load(f)
# 打印下载地址数量
count_1 = len(data)
print('下载地址数量:', len(data),count_1)
# 定义下载函数
def download(max_threads):
# 检查用户是否已经选择了json文件
if not file_path_var.get():
messagebox.showinfo('提示', '请先选择json文件')
return
# 读取本地json文件
#创建日志目录
os.makedirs(url_entry.get()+'/logs', exist_ok=True)
logging.basicConfig(filename=url_entry.get()+'/logs/download.log', level=logging.ERROR)
with open(file_path_var.get(), 'r') as f:
data = json.load(f)
# 创建锁对象
lock = threading.Lock()
# 创建线程池
with ThreadPoolExecutor(max_workers=max_threads) as executor:
# 创建 event 对象
event = threading.Event()
event.set() # 初始状态为 True
# 创建 tkinter.StringVar() 对象
label_var = tk.StringVar()
label_var.set('等待下载...')
label = tk.Label(window, textvariable=label_var)
label.pack()
# 遍历下载地址并下载文件
count = 0
for download_url in data:
# 获取下载文件的目录
count += 1
directory = os.path.join(url_entry.get(), *download_url.split('/')[1:-1])
# 提交任务到线程池
executor.submit(download_file, download_url, directory, lock, event, label_var,count)
# 检查 event 对象的状态,如果为 False,则暂停下载
while not event.is_set():
pass
# 定义暂停下载函数
def pause_download():
event.clear()
# 定义恢复下载函数
def resume_download():
event.set()
# 创建窗口
window = tk.Tk()
window.title('批量下载')
window.geometry('400x300')
# 创建选择文件按钮
file_path_var = tk.StringVar()
file_path_label = tk.Label(window, textvariable=file_path_var)
file_path_label.pack()
choose_file_button = tk.Button(window, text='选择文件', command=choose_file)
choose_file_button.pack()
# 创建线程数量标签和文本框
thread_label = tk.Label(window, text='线程数量:')
thread_label.pack()
thread_entry = tk.Entry(window)
thread_entry.insert(0, '10')
thread_entry.pack()
# 创建下载地址标签和文本框
url_label = tk.Label(window, text='下载地址:')
url_label.pack()
url_entry = tk.Entry(window)
url_entry.pack()
url_entry.insert(0, '6290')
# 创建下载按钮
download_button = tk.Button(window, text='下载', command=lambda: threading.Thread(target=download, args=(int(thread_entry.get()),)).start())
download_button.pack()
# 创建暂停按钮和恢复按钮
pause_button = tk.Button(window, text='暂停', command=pause_download)
pause_button.pack()
resume_button = tk.Button(window, text='恢复', command=resume_download)
resume_button.pack()
download_button.place(x=130, y=160)
pause_button.place(x=180, y=160)
resume_button.place(x=230, y=160)
# 运行窗口
window.mainloop()
import logging
import threading
from concurrent.futures import ThreadPoolExecutor
import json
import os
import tkinter as tk
from tkinter import filedialog, messagebox
def download(max_threads):
# 检查用户是否已经选择了json文件
if not file_path_var.get():
messagebox.showinfo('提示', '请先选择json文件')
return
# 读取本地json文件
os.makedirs(url_entry.get()+'/logs', exist_ok=True)
logging.basicConfig(filename=url_entry.get()+'/logs/download.log', level=logging.ERROR)
with open(file_path_var. get(), 'r') as f:
data = json.load(f)
lock = threading.Lock()
# 创建事件对象
event = threading.Event()
event.set()
# 定义下载标志
downloading = True
with ThreadPoolExecutor(max_workers=max_threads) as executor:
label_var = tk.StringVar()
label_var.set('等待下载...')
label = tk.Label(window, textvariable=label_var)
label.pack()
count = 0
for download_url in data:
directory = os.path.join(url_entry.get(), *download_url.split('/')[1:-1])
count += 1
if downloading:
executor.submit(download_file, download_url, directory, lock, event, label_var,count)
# 在等待时,检查下载是否被暂停
while not event.is_set():
if not downloading:
event.wait()
else:
while not downloading:
event.wait()
label_var.set('下载完成')
# 定义暂停和恢复函数
def pause_download():
global downloading, event
downloading =False
event.clear()
messagebox.showinfo('提示', '下载已暂停')
def resume_download():
global downloading, event
if not downloading:
downloading = True
event.set()import logging
import threading
from concurrent.futures import ThreadPoolExecutor
import json
import os
import tkinter as tk
from tkinter import filedialog, messagebox
def download(max_threads):
# 检查用户是否已经选择了json文件
if not file_path_var.get():
messagebox.showinfo('提示', '请先选择json文件')
return
# 读取本地json文件
os.makedirs(url_entry.get()+'/logs', exist_ok=True)
logging.basicConfig(filename=url_entry.get()+'/logs/download.log', level=logging.ERROR)
with open(file_path_var. get(), 'r') as f:
data = json.load(f)
lock = threading.Lock()
# 创建事件对象
event = threading.Event()
event.set()
# 定义下载标志
downloading = True
with ThreadPoolExecutor(max_workers=max_threads) as executor:
label_var = tk.StringVar()
label_var.set('等待下载...')
label = tk.Label(window, textvariable=label_var)
label.pack()
count = 0
for download_url in data:
directory = os.path.join(url_entry.get(), *download_url.split('/')[1:-1])
count += 1
if downloading:
executor.submit(download_file, download_url, directory, lock, event, label_var,count)
# 在等待时,检查下载是否被暂停
while not event.is_set():
if not downloading:
event.wait()
else:
while not downloading:
event.wait()
label_var.set('下载完成')
# 定义暂停和恢复函数
def pause_download():
global downloading, event
downloading =False
event.clear()
messagebox.showinfo('提示', '下载已暂停')
def resume_download():
global downloading, event
if not downloading:
downloading = True
event.set()
这样试试?
|
|