允许设置最大下载进程数量,自动分配列表中的下载量到每个下载进程,每个地址下载后有记录是否成功下载,将需要下载的文件地址列表放在名为tasksrc.txt文本文件中,格式如下:
使用相对路径,基址需要改后面的批处理代码中的$url_base变量。也可以在这个列表文件中使用绝对地址,但$url_base应该为空。
johnfine/8254ex04.zip
johnfine/8254ex05.zip
johnfine/bootf02.zip
johnfine/bootp02.zip
johnfine/bootr01.zip
johnfine/index.htm
johnfine/jloc.htm
johnfine/jloc07.zip
johnfine/pci07.zip
johnfine/pcopy02.zip
johnfine/pmcom02.zip
johnfine/segments.htm
johnfine/smbmbr03.zip
johnfine/tasktes1.zip
johnfine/v86call3.zip
johnfine/v86test2.zip
johnfine/vload04.zip
以下是批处理代码:
:script_begin
echo off
title multi-task download.
setlocal enabledelayedexpansion
::# 多任务时,允许最大工作者(进程)数量.
set $worker_num=10
::# 每个工作者所分配的任务数量。
set $tasks_assign_of_worker_0=1
set $tasks_alloc_num=0
::# 任务总数。
set $tasks_count=0
::# 当前工作者ID。
set $current_worker_id=1
::# 当前工作者所分配的任务数量。
set $current_worker_tasks=0
::# 任务分配源,一个文本文件列出下载地址。
set $file_task_source=tasksrc.txt
::# 下载失败信息的日志文件路径。
set $file_task_down_log=err.log
::# 下载完成信息的日志文件路径。
set $file_task_comp_log=comp_stat.log
::# 下载的文件保存目录。
set $folder_output=software
::# 运行时的临时目录。
set $folder_temp=tmp
::# 任务列表中相对的基地址。
set $url_base=http://www.xb312.com/Books/
::# 判断是否为子程式调用。
if "%~1" gtr "0" goto :download
::# 删除之前的日志文件。
if exist "%$file_task_comp_log%" (
erase /f /q "%$file_task_comp_log%")
if exist "%$file_task_down_log%" (
erase /f /q "%$file_task_down_log%")
::# 计算总共多少个下载地址。
if exist "%$file_task_source%" (
for /f "delims=:" %%i in (%$file_task_source%) do (
set /a $tasks_count=$tasks_count+=1))
::# 如果下载地址数量为零。
if $tasks_count equ 0 goto :error
::# 删除之前的临时目录。
if exist "%$folder_temp%\" (
2>&1>nul rmdir /s /q "%$folder_temp%")
2>&1>nul mkdir "%$folder_temp%"
::# 清除工作者ID所分配的任务数量
for /f "delims==" %%i in ('set $tasks_assign_of_worker_') do (
set %%i=)
::# 计算每工作者平均任务数量。
set /a $tasks_alloc_num=$tasks_count / $worker_num
::# 为每个工作者设置任务数量。
for /l %%i in (1,1,%$worker_num%) do (
set /a $tasks_assign_of_worker_%%i=$tasks_alloc_num)
::# 计算平均数后的剩余的任务数。
set /a $tasks_alloc_num=$tasks_count %% $worker_num
::# 将剩余任务分配给各工作者。
for /l %%i in (1,1,%$tasks_alloc_num%) do (
set /a $tasks_assign_of_worker_%%i+=1)
set $tasks_alloc_num=0
set $current_worker_id=1
call set $current_worker_tasks=%%$tasks_assign_of_worker_%$current_worker_id%%%
::# 根据每工作者所分的任务数量进行下载地址分配。
for /f "delims==" %%i in (%$file_task_source%) do (
echo.%%~i>>"%$folder_temp%\task_list!$current_worker_id!.txt"
set /a $current_worker_tasks-=1
if !$current_worker_tasks! equ 0 (
set /a $current_worker_id+=1
call set $current_worker_tasks=%%$tasks_assign_of_worker_!$current_worker_id!%%))
::# 启动每个工作者。
for /l %%i in (1,1,%$worker_num%) do (
start /MIN cmd.exe /c call "%~0" %%i )
goto :script_exit
:error
echo. no tasks.
:script_exit
goto :eof
:download
set $down_count=0
::# 获得当前工作者分配的总任务数量。
call set $current_worker_tasks=%%$tasks_assign_of_worker_%~1%%
::# 从地址列表中按顺序下载每个文件。
if exist "%$folder_temp%\task_list%~1.txt" (
for /f "delims=:" %%i in (%$folder_temp%\task_list%~1.txt) do (
2>&1>nul wget -nc -t 3 -P "%$folder_output%" %$url_base%"%%~i" && (
echo. PASS ===^> %%~i>>%$file_task_down_log%) || (
echo. FAIL ===^> %%~i>>%$file_task_down_log%)
set /a $down_count+=1
title !$down_count! of %$current_worker_tasks%)
erase /f /q %$folder_temp%\task_list%~1.txt)
::# 下载完成后记录到日志。
echo. task %~1 completed.>>%$file_task_comp_log%
::# 如果全部下载完成,删除临时目录。
set $remains_files=0
for %%i in (%$folder_temp%\*.*) do (
set /a $remains_files+=1)
if %$remains_files% equ 0 (
rmdir /s /q %$folder_temp%)