如何用 Python 打造一款超大文件下载器(以 HUTB 模拟器下载为例)
为大家分享一个实用的 Python 工具(HUTB 模拟器发行版下载工具),它能自动从仓库下载发行版,合并分块文件并解压,最终为用户提供可执行的完整软件包。

注意
如果仅使用,可以直接从该链接直接下载: https://gitee.com/OpenHUTB/sw/releases/download/up/hutb_downloader.exe ,双击 hutb_download.exe 后会在当前目录下载整个模拟器(下载或运行时可能会报警告,忽视即可),点击hutb/CarlaUE4.exe即可启动模拟器。
一、为什么需要这样的工具?
在开源项目分发中,开发者常常面临一个难题:如何让用户方便地获取最新的发行版?传统的方式是提供直接的下载链接,但这种方式有几个明显的缺点:
-
更新麻烦:每次发布新版本都需要手动更新下载链接
-
大文件传输问题:Git对于大文件支持不够友好
-
下载体验差:用户需要手动执行多个步骤才能使用软件
我们的解决方案是:将大文件分割成小块上传到仓库(大文件仓库对最大文件有限制),然后通过一个智能下载器自动下载、合并并解压这些文件。这样既解决了大文件存储问题,又为用户提供了便捷的一键下载体验。
二、工具的核心设计
2.1 技术选型:为什么选择Python?
Python 以其简洁的语法和丰富的第三方库而闻名。对于这个项目,我们主要利用了以下几个库:
-
GitPython:提供与Git仓库交互的高级接口
-
shutil:用于文件和目录的高级操作
-
zipfile:处理ZIP压缩文件
-
os:提供操作系统相关功能
这些库的组合使得我们能够以相对简单的代码实现复杂的功能。
2.2 架构设计
整个工具的核心是一个名为 GitRepository 的类,它封装了与Git仓库交互的所有操作。让我们看看这个类的设计亮点:
class GitRepository(object):
"""
git仓库管理
"""
def __init__(self, local_path, repo_url, branch='master'):
self.local_path = local_path
self.repo_url = repo_url
self.repo = None
self.initial(repo_url, branch)
def initial(self, repo_url, branch):
"""
初始化git仓库
:param repo_url:
:param branch:
:return:
"""
if not os.path.exists(self.local_path):
os.makedirs(self.local_path)
git_local_path = os.path.join(self.local_path, '.git')
if not is_git_dir(git_local_path):
self.repo = Repo.clone_from(repo_url, to_path=self.local_path, branch=branch, progress=Progress(), depth=1)
else:
self.repo = Repo(self.local_path)
三、关键技术实现
3.1 智能下载:断点续传与进度显示
为了提升用户体验,我们实现了下载进度显示功能。通过继承git.remote.RemoteProgress类,我们可以实时获取下载进度:
class Progress(git.remote.RemoteProgress):
def update(self, op_code, cur_count, max_count=None, message=""):
print(
'Download (operation code: %s, current count: %s, max count: %s, percentage: %s, message: %s)...'%(
op_code,
cur_count,
max_count,
cur_count / (max_count or 100.0),
message or "NO MESSAGE",
)
)
3.2 大文件处理:分块与合并
由于Git对单个文件大小有限制,我们需要将大文件分割成多个小块。这里我们实现了两个关键函数:
文件分割函数:
def split_file(input_file, output_dir, chunk_size):
with open(input_file, 'rb') as f:
index = 0
while True:
chunk = f.read(chunk_size)
if not chunk:
break
# 按0对齐为了保证合并时也是按顺序进行合并
output_file = os.path.join(output_dir, f'hutb_{index:05d}.dat')
with open(output_file, 'wb') as out:
out.write(chunk)
index += 1
文件合并函数:
def merge_files(input_dir, output_file):
files = os.listdir(input_dir)
files.sort()
with open(output_file, 'wb') as out:
for file_name in files:
print("Merging file: ", file_name)
file_path = os.path.join(input_dir, file_name)
with open(file_path, 'rb') as f:
chunk = f.read()
out.write(chunk)
-
避免了Git对大文件的限制
-
可以并行下载多个小块,提高下载速度
-
如果某个小块下载失败,可以只重新下载该部分,实现类似断点续传的功能
3.3 权限管理:安全删除只读文件
在Windows系统中,Git创建的某些文件可能被设置为只读属性,这会导致在删除.git文件夹时出现权限错误。我们通过定义一个回调函数解决了这个问题:
def remove_readonly(func, path, _):
"Clear the readonly bit and reattempt the removal"
os.chmod(path, stat.S_IWRITE)
func(path)
四、完整工作流程
4.1 初始化阶段
-
检查本地目录是否存在,如果存在则先删除旧版本
-
克隆Git仓库到本地(使用浅克隆以加快下载速度)
-
显示下载进度
4.2 清理阶段
-
删除.git文件夹和.gitattributes文件,这些是版本控制相关文件,普通用户不需要
-
确保下载目录的干净整洁
4.3 文件处理阶段
-
检查是否存在已合并的ZIP文件,如果没有则合并所有.dat文件
-
解压ZIP文件到当前目录
-
删除中间文件(ZIP文件和所有的.dat文件)
4.4 完成阶段
-
计算并显示整个下载过程耗时
-
准备就绪的软件可以直接使用
五、打包为可执行文件
为了让没有Python环境的用户也能使用这个工具,我们将其打包为独立的EXE文件。使用PyInstaller可以轻松实现这一目标:
pip install pyinstaller
pyinstaller download_from_git.py --onefile --name hutb_downloader.exe
-
单文件模式:--onefile参数将所有依赖打包到一个EXE文件中
-
避免杀毒软件误报:某些杀毒软件可能会将PyInstaller打包的程序误报为病毒。可以通过代码签名或调整打包参数来减少误报
-
图标定制:可以使用-i参数指定程序图标
六、实际应用场景
6.1 开源项目分发
对于开源项目维护者,这个工具可以集成到项目的发行流程中。每次发布新版本时,只需要将分块文件上传到Git仓库,用户就可以通过下载器获取最新版本。
6.2 企业内部软件更新
在企业环境中,可以使用这个工具来分发内部软件。通过控制Git仓库的访问权限,可以确保只有授权用户能够下载软件。
6.3 教育用途
在计算机教育中,教师可以使用这个工具分发教学材料和软件环境,学生只需要运行一个简单的命令就能获得完整的学习环境。
七、性能测试
根据实际测试,在网络带宽足够的情况下,整个下载过程大约 2 分钟,合并和解压等操作大约需要 2 分钟。这个时间主要包括:
-
Git仓库克隆:2-3分钟
-
文件合并:1-2分钟
-
文件解压:30秒-1分钟
八、总结
通过这个Python实现的Git发行版下载器,我们解决了大文件通过Git分发的难题,为用户提供了便捷的一键下载体验。这个工具展示了Python在自动化任务处理方面的强大能力,也体现了模块化的软件设计原则。
无论是对于开源项目维护者,还是企业内部的软件分发,这个工具都提供了一个高效、可靠的解决方案。随着Git在软件开发中的普及,类似的工具将会在软件分发领域发挥越来越重要的作用。
随着技术的不断发展,我们还可以在这个基础上添加更多高级功能,如自动更新、多线程下载、图形界面等,使其成为一个更加完善的软件分发解决方案。希望这个工具的开发思路和实现方法能够给大家带来启发,也期待看到更多基于这个思想的创新应用。
版权声明:本文介绍的代码仅供学习参考,工具代码遵循 MIT 开源协议。
- 源代码:https://github.com/OpenHUTB/hutb
- 文档:https://openhutb.github.io