如何在调用shutil.make_archive前排序文件,让mimetype处于归档目录顶部?
解决shutil.make_archive打包后mimetype文件位置问题
问题原因
shutil.make_archive创建zip归档时,默认是按文件名的字典序排列条目,和文件创建顺序无关。你的两个子目录以d开头,mimetype以m开头,字典序里d在m前面,所以打包后mimetype会排在最后。
解决方案:用zipfile手动控制归档顺序
要让mimetype排在首位,得绕过shutil的默认逻辑,直接用zipfile模块手动构建归档,完全控制文件添加顺序。
修改后的代码示例
import os import zipfile # 原有的目录创建逻辑不变 os.makedirs("mainDirectory", exist_ok=True) os.chdir("mainDirectory") # 创建mimetype文件 with open("mimetype", "w", encoding="ASCII") as file: file.write("application/epub+zip") # 替换成你的实际内容 # 创建子目录并处理内容 os.makedirs("directory1") os.makedirs("directory2") # 这里执行你对directory1和directory2的修改操作 # 返回上级目录准备打包 os.chdir("..") # 手动构建zip归档 with zipfile.ZipFile("mainDirectory.zip", "w", zipfile.ZIP_DEFLATED) as zipf: # 先添加mimetype文件,EPUB等规范要求该文件不压缩,所以用ZIP_STORED mimetype_full_path = os.path.join("mainDirectory", "mimetype") zipf.write(mimetype_full_path, arcname="mainDirectory/mimetype", compress_type=zipfile.ZIP_STORED) # 按你想要的顺序添加剩余条目 remaining_items = [ os.path.join("mainDirectory", "directory1"), os.path.join("mainDirectory", "directory2") ] # 递归添加子目录下的所有文件 for item in remaining_items: if os.path.isdir(item): for root, _, files in os.walk(item): for file in files: file_path = os.path.join(root, file) # 计算归档内的相对路径 arc_path = os.path.relpath(file_path, os.getcwd()) zipf.write(file_path, arcname=arc_path) else: arc_path = os.path.relpath(item, os.getcwd()) zipf.write(item, arcname=arc_path)
关键注意点
- 强制顺序:先添加mimetype,再添加其他内容,确保它在归档最前面。
- 压缩方式:如果是制作EPUB这类有规范要求的文件,必须给mimetype用
ZIP_STORED不压缩,否则文件可能无法被识别。普通zip可按需选择压缩方式。 - 递归遍历:用
os.walk确保子目录里的所有文件都被正确打包。
不推荐的替代方案
要是不想改代码结构,你可以给mimetype加前缀,比如00-mimetype,让它在字典序里排第一。但这种方法可能破坏某些格式的规范(比如EPUB要求文件名必须是mimetype),所以不建议用。
内容的提问来源于stack exchange,提问作者Ironfort 9
相关产品推荐
相关产品推荐

