4.11 Python3 数据压缩模块

Python 标准库提供了多个用于数据压缩的模块,包括:

  zlibgzipbz2zipfile 、tarfile

这些模块可以处理不同格式的压缩文件和压缩数据流。


目录

1. zlib 模块

基本用法

高级功能

2. gzip 模块

读写 gzip 文件

3. bz2 模块

基本用法

4. zipfile 模块

创建 ZIP 文件

读取 ZIP 文件

5. tarfile 模块

创建 tar 归档

读取 tar 归档

6. 性能比较与选择建议

6. 实际应用示例

1. 压缩日志文件

2. 创建加密的 ZIP 文件

3. 增量备份目录

注意事项


1. zlib 模块

zlib 模块提供了对 zlib 库的访问,用于数据的压缩和解压缩。

基本用法

import zlib

# 压缩数据
data = b"Some data to compress" * 100
compressed_data = zlib.compress(data)
print(f"原始大小: {len(data)}, 压缩后: {len(compressed_data)}")

# 解压数据
decompressed_data = zlib.decompress(compressed_data)
assert data == decompressed_data

高级功能

# 使用压缩级别 (0-9)
compressed = zlib.compress(data, level=9)

# 创建压缩/解压缩对象
compressor = zlib.compressobj(level=9)
chunk1 = compressor.compress(data[:100])
chunk2 = compressor.compress(data[100:])
final_chunk = compressor.flush()

decompressor = zlib.decompressobj()
result = decompressor.decompress(chunk1 + chunk2 + final_chunk)

2. gzip 模块

gzip 模块提供了对 GNU zip 文件的读写接口。

读写 gzip 文件

import gzip
import shutil

# 写入 gzip 文件
with gzip.open('example.txt.gz', 'wb') as f:
    f.write(b"Some data to compress" * 100)

# 读取 gzip 文件
with gzip.open('example.txt.gz', 'rb') as f:
    content = f.read()
    print(content)

# 压缩现有文件
with open('large_file.txt', 'rb') as f_in:
    with gzip.open('large_file.txt.gz', 'wb') as f_out:
        shutil.copyfileobj(f_in, f_out)

3. bz2 模块

bz2 模块提供了对 bzip2 压缩算法的支持。

基本用法

import bz2

# 压缩数据
data = b"Some data to compress" * 100
compressed = bz2.compress(data)
print(f"压缩率: {len(compressed)/len(data):.1%}")

# 解压数据
decompressed = bz2.decompress(compressed)
assert data == decompressed

# 文件操作
with bz2.open('example.bz2', 'wb') as f:
    f.write(b"This is a bzip2 compressed file")

4. zipfile 模块

zipfile 模块用于处理 ZIP 归档文件。

创建 ZIP 文件

import zipfile

# 创建 ZIP 文件并添加文件
with zipfile.ZipFile('archive.zip', 'w') as zipf:
    zipf.write('file1.txt')
    zipf.write('file2.txt', arcname='renamed.txt')  # 指定归档中的名称

# 添加目录
with zipfile.ZipFile('archive.zip', 'w') as zipf:
    zipf.write('my_directory')  # 添加整个目录

读取 ZIP 文件

# 列出 ZIP 文件内容
with zipfile.ZipFile('archive.zip', 'r') as zipf:
    print(zipf.namelist())  # 列出所有文件
    
    # 提取单个文件
    zipf.extract('file1.txt', 'extract_dir')
    
    # 提取所有文件
    zipf.extractall('extract_all_dir')

# 读取 ZIP 中的文件内容
with zipfile.ZipFile('archive.zip') as zipf:
    with zipf.open('file1.txt') as f:
        content = f.read()
        print(content)

5. tarfile 模块

tarfile 模块用于处理 tar 归档文件,支持 gzip 和 bzip2 压缩。

创建 tar 归档

import tarfile

# 创建未压缩的 tar 文件
with tarfile.open('archive.tar', 'w') as tar:
    tar.add('file1.txt')
    tar.add('my_directory')

# 创建 gzip 压缩的 tar 文件
with tarfile.open('archive.tar.gz', 'w:gz') as tar:
    tar.add('file1.txt')

# 创建 bzip2 压缩的 tar 文件
with tarfile.open('archive.tar.bz2', 'w:bz2') as tar:
    tar.add('file1.txt')

读取 tar 归档

# 列出 tar 文件内容
with tarfile.open('archive.tar.gz', 'r:gz') as tar:
    print(tar.getnames())  # 列出所有成员
    
    # 提取单个文件
    tar.extract('file1.txt', 'extract_dir')
    
    # 提取所有文件
    tar.extractall('extract_all_dir')

# 读取 tar 中的文件内容
with tarfile.open('archive.tar.gz', 'r:gz') as tar:
    member = tar.getmember('file1.txt')
    f = tar.extractfile(member)
    content = f.read()
    print(content)

6. 性能比较与选择建议

  1. zlib/gzip

    • 压缩速度较快

    • 压缩率中等

    • 适合网络传输和一般文件压缩

  2. bz2

    • 压缩速度较慢

    • 压缩率较高

    • 适合需要高压缩率且不频繁访问的场景

  3. zipfile

    • 支持多文件归档

    • 广泛兼容

    • 适合打包多个文件

  4. tarfile + 压缩:

    • 保留文件权限和元数据

    • 适合 Unix/Linux 系统备份

    • 结合 gzip/bzip2 提供压缩功能


6. 实际应用示例

1. 压缩日志文件

import gzip
import shutil
from pathlib import Path

def compress_logs(log_dir, output_dir):
    output_dir = Path(output_dir)
    output_dir.mkdir(exist_ok=True)
    
    for log_file in Path(log_dir).glob('*.log'):
        with open(log_file, 'rb') as f_in:
            with gzip.open(output_dir / f"{log_file.name}.gz", 'wb') as f_out:
                shutil.copyfileobj(f_in, f_out)
        print(f"Compressed {log_file} to {output_dir/log_file.name}.gz")

2. 创建加密的 ZIP 文件

import zipfile
import os

def create_encrypted_zip(output_filename, files_to_zip, password):
    with zipfile.ZipFile(output_filename, 'w', zipfile.ZIP_DEFLATED) as zipf:
        for file in files_to_zip:
            zipf.write(file, arcname=os.path.basename(file))
        
        # 设置密码 (Python 3.6+)
        zipf.setpassword(password.encode('utf-8'))
    
    print(f"Created encrypted archive: {output_filename}")

3. 增量备份目录

import tarfile
import time
import os

def incremental_backup(source_dir, backup_file):
    # 只备份最近修改的文件
    cutoff = time.time() - 24 * 3600  # 24小时前
    
    with tarfile.open(backup_file, 'w:gz') as tar:
        for root, dirs, files in os.walk(source_dir):
            for file in files:
                path = os.path.join(root, file)
                mtime = os.path.getmtime(path)
                if mtime > cutoff:
                    tar.add(path)
                    print(f"Added {path} to backup")

注意事项

  1. 内存使用:处理大文件时,考虑分块处理避免内存不足

  2. 文件权限:解压时注意文件权限设置,特别是在跨平台场景

  3. 路径安全:处理压缩文件时注意路径遍历攻击风险

  4. 编码问题:处理文件名时注意编码问题,特别是跨平台场景

  5. 资源清理:确保正确关闭文件句柄,使用 with 语句管理资源


这些压缩模块为 Python 提供了强大的数据压缩和归档功能,可以根据具体需求选择合适的模块和压缩算法。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值