本文目录导读:

我来为您介绍几种Python批量压缩文件的方法:
使用zipfile模块压缩文件夹
import zipfile
import os
from pathlib import Path
def batch_zip_folders(source_dir, output_dir=None):
"""
批量压缩文件夹中的每个子文件夹
Args:
source_dir: 源目录路径
output_dir: 输出目录路径(默认与源目录相同)
"""
source_path = Path(source_dir)
if output_dir is None:
output_dir = source_dir
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
# 遍历所有子文件夹
for folder_path in source_path.iterdir():
if folder_path.is_dir():
# 创建zip文件名
zip_name = f"{folder_path.name}.zip"
zip_path = output_path / zip_name
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
# 遍历文件夹中的所有文件
for file_path in folder_path.rglob('*'):
if file_path.is_file():
# 计算相对路径,保持目录结构
arcname = file_path.relative_to(folder_path)
zipf.write(file_path, arcname)
print(f"已压缩: {folder_path.name} -> {zip_name}")
# 使用示例
batch_zip_folders("/path/to/source/folder")
批量压缩指定文件列表
import zipfile
from pathlib import Path
def batch_zip_files(file_list, output_zip_name="batch.zip"):
"""
将多个文件压缩到同一个zip文件中
Args:
file_list: 文件路径列表
output_zip_name: 输出zip文件名
"""
with zipfile.ZipFile(output_zip_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in file_list:
file_path = Path(file_path)
if file_path.exists():
# 使用文件名作为存档名称
zipf.write(file_path, file_path.name)
print(f"已添加: {file_path.name}")
else:
print(f"文件不存在: {file_path}")
# 使用示例
files_to_compress = [
"/path/to/file1.txt",
"/path/to/file2.jpg",
"/path/to/file3.pdf"
]
# 压缩到同一个文件
batch_zip_files(files_to_compress, "my_files.zip")
高级版本:支持多格式压缩
import zipfile
import tarfile
import gzip
import shutil
from pathlib import Path
from typing import Union, List
class BatchCompressor:
"""批量压缩工具类"""
def __init__(self, compression_type='zip'):
"""
初始化压缩器
Args:
compression_type: 'zip', 'tar', 'gz', 'targz'
"""
self.compression_type = compression_type
def compress_single_folder(self, folder_path: Path, output_path: Path):
"""压缩单个文件夹"""
folder_path = Path(folder_path)
output_path = Path(output_path)
# 确保输出目录存在
output_path.parent.mkdir(parents=True, exist_ok=True)
if self.compression_type == 'zip':
self._compress_to_zip(folder_path, output_path)
elif self.compression_type == 'tar':
self._compress_to_tar(folder_path, output_path)
elif self.compression_type == 'targz':
self._compress_to_targz(folder_path, output_path)
elif self.compression_type == 'gz':
self._compress_to_gz(folder_path, output_path)
def _compress_to_zip(self, folder_path: Path, output_path: Path):
"""压缩为zip格式"""
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in folder_path.rglob('*'):
if file_path.is_file():
arcname = file_path.relative_to(folder_path)
zipf.write(file_path, arcname)
def _compress_to_tar(self, folder_path: Path, output_path: Path):
"""压缩为tar格式"""
with tarfile.open(output_path, 'w') as tar:
tar.add(folder_path, arcname=folder_path.name)
def _compress_to_targz(self, folder_path: Path, output_path: Path):
"""压缩为tar.gz格式"""
with tarfile.open(output_path, 'w:gz') as tar:
tar.add(folder_path, arcname=folder_path.name)
def _compress_to_gz(self, folder_path: Path, output_path: Path):
"""压缩为gz格式(仅压缩文件,不保留目录结构)"""
with open(folder_path, 'rb') as f_in:
with gzip.open(output_path, 'wb') as f_out:
shutil.copyfileobj(f_in, f_out)
def batch_compress(self, source_dir: Union[str, Path],
output_dir: Union[str, Path] = None,
pattern: str = "*"):
"""
批量压缩文件夹
Args:
source_dir: 源目录
output_dir: 输出目录
pattern: 文件匹配模式(如 "*.txt")
"""
source_path = Path(source_dir)
if output_dir is None:
output_dir = source_path
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
compressed_count = 0
for folder_path in source_path.iterdir():
if folder_path.is_dir():
# 生成输出文件名
ext = {
'zip': '.zip',
'tar': '.tar',
'targz': '.tar.gz',
'gz': '.gz'
}.get(self.compression_type, '.zip')
output_file = output_path / f"{folder_path.name}{ext}"
try:
self.compress_single_folder(folder_path, output_file)
print(f"✅ 已压缩: {folder_path.name} -> {output_file.name}")
compressed_count += 1
except Exception as e:
print(f"❌ 压缩失败: {folder_path.name} - {str(e)}")
print(f"\n总计压缩: {compressed_count} 个文件夹")
# 使用示例
if __name__ == "__main__":
# 创建压缩器实例
compressor = BatchCompressor(compression_type='zip')
# 批量压缩所有子文件夹
compressor.batch_compress(
source_dir="/path/to/source",
output_dir="/path/to/output"
)
# 添加进度显示
compressor.batch_compress(
source_dir="/path/to/source",
output_dir="/path/to/output",
verbose=True # 如果需要详细输出
)
并行压缩(提高效率)
import zipfile
from pathlib import Path
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading
class ParallelBatchCompressor:
"""并行批量压缩器"""
def __init__(self, max_workers=4):
self.max_workers = max_workers
self.lock = threading.Lock()
def compress_folder(self, folder_path: Path, output_dir: Path):
"""压缩单个文件夹"""
folder_path = Path(folder_path)
output_dir = Path(output_dir)
zip_name = f"{folder_path.name}.zip"
zip_path = output_dir / zip_name
try:
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
for file_path in folder_path.rglob('*'):
if file_path.is_file():
arcname = file_path.relative_to(folder_path)
zipf.write(file_path, arcname)
with self.lock:
print(f"✅ 已完成: {folder_path.name}")
return True, folder_path.name
except Exception as e:
with self.lock:
print(f"❌ 失败: {folder_path.name} - {str(e)}")
return False, folder_path.name
def batch_compress_parallel(self, source_dir: Union[str, Path],
output_dir: Union[str, Path] = None):
"""并行批量压缩"""
source_path = Path(source_dir)
if output_dir is None:
output_dir = source_path
output_path = Path(output_dir)
output_path.mkdir(parents=True, exist_ok=True)
# 获取所有子文件夹
folders = [f for f in source_path.iterdir() if f.is_dir()]
print(f"找到 {len(folders)} 个文件夹需要压缩")
# 使用线程池并行压缩
with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
# 提交所有压缩任务
future_to_folder = {
executor.submit(self.compress_folder, folder, output_path): folder
for folder in folders
}
# 收集结果
success_count = 0
for future in as_completed(future_to_folder):
success, name = future.result()
if success:
success_count += 1
print(f"\n压缩完成! 成功: {success_count}/{len(folders)}")
# 使用示例
compressor = ParallelBatchCompressor(max_workers=4)
compressor.batch_compress_parallel("/path/to/source")
实用案例:压缩指定类型的文件
import zipfile
from pathlib import Path
def compress_by_pattern(source_dir, patterns=["*.txt", "*.jpg"], output_name="selected.zip"):
"""
压缩目录中指定模式的文件
Args:
source_dir: 源目录
patterns: 文件模式列表
output_name: 输出文件名
"""
source_path = Path(source_dir)
with zipfile.ZipFile(output_name, 'w', zipfile.ZIP_DEFLATED) as zipf:
for pattern in patterns:
for file_path in source_path.rglob(pattern):
if file_path.is_file():
# 保持相对路径
arcname = file_path.relative_to(source_path)
zipf.write(file_path, arcname)
print(f"已添加: {arcname}")
print(f"\n压缩完成: {output_name}")
# 使用示例
compress_by_pattern(
source_dir="/path/to/documents",
patterns=["*.pdf", "*.docx", "*.txt"],
output_name="documents_backup.zip"
)
注意事项
- 路径处理:使用
Path对象处理路径,避免跨平台问题 - 大文件处理:对于大文件,考虑使用分块压缩或并行压缩
- 内存管理:处理大量文件时,注意内存使用
- 错误处理:添加异常处理,避免程序崩溃
- 进度显示:对大量文件压缩时,添加进度显示
这些示例涵盖了大多数批量压缩的场景,您可以根据具体需求选择合适的方案。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播