|
|
方法 1:读取文件头部魔数(最推荐、精准,不依赖后缀)
ZIP 文件固定文件头标识:50 4B(十六进制),对应字节 b'PK'
所有标准 zip 文件开头两个字节都是 PK,哪怕后缀被篡改也能识别。
- def is_zip_file(file_path: str) -> bool:
- try:
- with open(file_path, 'rb') as f:
- header = f.read(2) # 读取前2字节
- return header == b'PK'
- except (FileNotFoundError, PermissionError):
- # 文件不存在/无读取权限,判定不是zip
- return False
- # 使用
- print(is_zip_file("test.zip"))
- print(is_zip_file("demo.txt"))
复制代码
方法 2:使用内置 zipfile 模块(官方标准,可顺带校验完整性)
尝试打开文件,无报错即为合法 zip 文件,可区分损坏的压缩包:
- import zipfile
- def is_zip_file(file_path: str) -> bool:
- try:
- with zipfile.ZipFile(file_path) as zf:
- # 校验压缩包完整性
- zf.testzip()
- return True
- except (zipfile.BadZipFile, FileNotFoundError, PermissionError):
- return False
复制代码
优缺点:
✅ 能识别破损、无效 zip 包
❌ 相比读文件头速度稍慢
方法 3:仅判断文件后缀(不推荐,极易被篡改)
只看文件名结尾,修改后缀就能骗过判断:
- def is_zip_file_suffix(file_path: str) -> bool:
- return file_path.lower().endswith((".zip", ".zipx"))
复制代码
补充边界场景
空文件:前 2 字节为空,会判定非 zip
分卷压缩包、加密 zip:头部依旧是 PK,两种方法均可识别
jar/apk 文件:本质都是 zip 格式,同样会被识别为 zip
组合实用写法(兼顾精准 + 容错)
优先文件头校验,再用 zipfile 二次核验:
- import zipfile
- def check_zip(filepath):
- # 第一步校验文件头
- try:
- with open(filepath, "rb") as f:
- if f.read(2) != b"PK":
- return False
- except:
- return False
- # 第二步校验zip结构合法
- try:
- zipfile.ZipFile(filepath)
- return True
- except zipfile.BadZipFile:
- return False
复制代码
|
|