gzip.open()读.gz文件需用'rt'模式并指定encoding,shutil.unpack_archive()不支持单.gz文件,gzip.decompress()适用于小文件内存解压,判断.gz格式应使用gzip.GzipFile校验而非后缀。

gzip.open() 读取 .gz 文件最常用也最容易出错
直接用 gzip.open() 打开 .gz 文件是默认方案,但默认编码是二进制模式,读出来的是 bytes,不是字符串。如果你直接 .read() 后打印或正则匹配,大概率遇到 UnicodeDecodeError。
正确做法是显式指定 encoding 参数:
import gzip
with gzip.open('data.txt.gz', 'rt', encoding='utf-8') as f:
content = f.read()注意三个关键点:
-
'rt'表示文本模式(read +text),不能写成'r'(那是二进制) - 必须加
encoding,否则 Python 3 下gzip.open(..., 'rt')会尝试用系统默认编码(如 Windows 的 cp1252),不是 UTF-8 - 如果文件实际是 GBK、ISO-8859-1 等编码,
encoding要对应改,否则乱码
shutil.unpack_archive() 不支持 .gz 单文件解压
很多人搜 “Python 解压 gz”,看到 shutil.unpack_archive() 就直接用,结果报错:ValueError: Unknown archive format '.gz'。这是因为 shutil.unpack_archive() 只支持 .zip、.tar、.gztar(即 .tar.gz)这类归档格式,不支持纯 .gz(单文件压缩)。
立即学习“Python免费学习笔记(深入)”;
如果你手头是 log.gz 这种单个文件压缩,别用 shutil.unpack_archive() —— 它根本不管用。
真正能处理单 .gz 的只有:gzip 库本身,或配合 shutil.copyfileobj() 做流式解压到文件:
import gzip import shutilwith gzip.open('input.gz', 'rb') as f_in: with open('output.txt', 'wb') as f_out: shutil.copyfileobj(f_in, f_out)
gzip.decompress() 适合内存小、内容短的场景
当你已经用 open(..., 'rb') 读入了整个 .gz 文件的字节内容(比如从网络响应、数据库 blob 中拿到),可以用 gzip.decompress() 直接解压:
import gzip
compressed_bytes = open('file.gz', 'rb').read()
decompressed_bytes = gzip.decompress(compressed_bytes)
text = decompressed_bytes.decode('utf-8')但要注意:
- 这个方法把整个压缩内容加载进内存再解压,不适合几百 MB 以上的
.gz文件 - 它不接受文件路径,只接受
bytes对象,所以不能代替gzip.open() - 如果原始压缩数据不是标准 gzip 格式(比如被截断、混入其他数据),会抛
OSError: Not a gzipped file
判断文件是否真的是 .gz 格式,别光看后缀
用户传来的文件叫 data.gz,不代表它真是 gzip 压缩的——可能后缀错了、文件损坏、或者根本是 zip 改名。靠后缀判断容易在生产环境翻车。
安全做法是用 gzip.GzipFile 尝试读取头部:
import gzipdef is_gz_file(filepath): try: with gzip.GzipFile(filepath) as f: f.read(1) # 只读 1 字节触发 header 检查 return True except OSError: return False
这个函数比检查 filepath.endswith('.gz') 可靠得多。如果返回 False,就该换别的解压逻辑,而不是硬上 gzip.open()。
gzip 格式头部有固定魔数 b'\x1f\x8b',但手动比对不如让 GzipFile 自己校验来得稳妥——它还会检查 CRC 和长度。











