压缩处理
zipfile
语法
with zipfile.ZipFile(output_name, "w") as z:
for each in file_list:
z.write(each, compress_type=zipfile.ZIP_DEFLATED)
注意:无论是py2还是py3,内置的
zipfile
模块在解压一些存在文件的zip文件时会出现乱码问题,解决方案是修正里面对中文decoe的处理
参数解析
compression
- ZIP_STORED(no compression)
- ZIP_DEFLATED(requires zlib)
- ZIP_BZIP2(requires bz2)
- ZIP_LZMA(requires lzma)
compresslevel
- None (default for the given compression type) or an integer
- specifying the level to pass to the compressor.
- When using ZIP_STORED or ZIP_LZMA this keyword has no effect.
- When using ZIP_DEFLATED integers 0 through 9 are accepted.
- When using ZIP_BZIP2 integers 1 through 9 are accepted.
使用示例
def dir_to_zip(
file_dir: str,
*,
output_name: str = None,
file_list: list[str] = None,
exclude: list[str] = list(),
) -> str:
"""
传入一个目录,将该目录压缩成zip文件
- param file_dir :{str} 要压缩的目录
- param output_name :{str} 压缩后导出的位置(绝对路径)
- param file_list=None :{list[str]} 指定哪些文件需要压缩,默认该目录下所有文件
- param exclude :{list[str]} 要排除的目录或者文件
@returns `{str}` 如果成功返回压缩包名字,如果失败返回空""字符串
@example
```python
tar_dir = r'xxxx/'
res = dir_to_zip(tar_dir)
if not res: return print('压缩失败')
```
"""
res = ""
if not output_name:
name = os.path.basename(file_dir).split(".")[0]
output_name = os.path.join(file_dir, f"{name}.zip")
if not file_list:
file_list = os.listdir(file_dir)
cur_dir = os.getcwd()
base_dir = os.path.basename(file_dir)
try:
os.chdir(file_dir)
with zipfile.ZipFile(output_name, "w") as z:
for each in file_list:
if each in exclude:
continue
z.write(each, compress_type=zipfile.ZIP_DEFLATED)
res = output_name
except Exception as e:
print("z.write fail: ", e)
finally:
os.chdir(cur_dir)
return res
def pack_dir(target_dir, to_file):
target_dir_dir = os.path.dirname(target_dir)
dir_name = os.path.basename(target_dir)
cur_dir = os.getcwd()
to_file_name = os.path.basename(to_file)
# 手动打开文件句柄替换zipfile打开文件句柄
with open(to_file, "wb") as dest, zipfile.ZipFile(dest, "w", zipfile.ZIP_DEFLATED) as f:
for root_dir, dir_list, file_list in os.walk(target_dir):
for name in file_list:
target_file = os.path.join(root_dir, name)
arcname = target_file.replace(target_dir_dir, "") # 这里去掉绝对路径指定压缩包里面的文件所在目录结构
f.write(target_file, arcname=arcname)
return to_file
tarfile
shutil.make_archive
这是一个快速解包,打包的命令,功能相对固定,如果需要深度定制,可以使用zipfile模块
基础语法
shutil.make_archive(
base_name,
format[, root_dir[, base_dir, verbose, dry_run, owner, group, logger])
参数解释
- base_name:压缩包的文件名,也可以是压缩包的路径;只是文件名时,则保存至当前目录下,否则保存至指定路径;
- format:压缩包种类,“zip”, “tar”, “bztar”,“gztar”;
- base_dir:指定要压缩文件的路径,可以指定路径下的文件名,也可以指定路径;
- root_dir:指定要压缩的路径根目录(默认当前目录),只能指定路径,优先级低于base_dir。
使用示例
错误示例
把当前目录下的文件压缩生成copy.zip文件到当前目录下
import shutil
shutil.make_archives('copy','zip')
注意:此操作会出现递归拷贝压缩导致文件损坏(当前目录下的copy.zip中会有copy.zip)
import shutil
shutil.make_archives('D:\copy3\copy','zip',base_dir='D:\copy2\\测试.txt')
shutil.unpack_archive
import shutil
shutil.unpack_archive('xxxx.zip')
代码实例
rar、zip、tgz、tar、gz
def uncompress(src_file, dest_dir):
"""
@Description 解压各种类型的压缩包
- param src_file :{file|str} 你要解压的压缩包文件
- param dest_dir :{str} 你要解压到的目标路径
@returns `{str}` 成功返回压缩路径,失败返回空
@example
```python
src_file = 'xxx.zip'
dest_dir = '你要解压到的目标路径'
res = uncompress(src_file, dest_dir)
# or
with open('你要解压的压缩包文件路径', 'rb') as src_file:
res = uncompress(src_file, dest_dir)
"""
if isinstance(src_file, str):
with open("你要解压的压缩包文件路径", "rb") as f:
src_file = f
_, file_type = os.path.splitext(src_file.filename)
try:
if file_type == ".zip":
import zipfile # 需要安装zip包:pip install zipp
zip_file = zipfile.ZipFile(src_file)
for names in zip_file.namelist():
zip_file.extract(names, dest_dir)
zip_file.close()
return dest_dir
elif file_type == ".rar":
try:
import rarfile # 需要安装rar包:pip install rarfile
rar = rarfile.RarFile(src_file)
os.chdir(dest_dir)
rar.extractall()
rar.close()
return dest_dir
except Exception as err:
print("uncompress rar fail: ", err)
return ""
elif file_type == ".tgz" or file_type == ".tar" or file_type == ".gz":
import tarfile # Python自带tarfile模块
tar = tarfile.open(fileobj=src_file)
for name in tar.getnames():
tar.extract(name, dest_dir)
tar.close()
return dest_dir
else:
print("不支持的格式: {}".format(file_type))
return ""
except Exception as ex:
print("uncompress fail: ", ex)
return ""
使用
if name == 'main': dest_dir = '你要解压到的目标路径' with open('你要解压的压缩包文件路径', 'rb') as src_file: result = uncompress(src_file, dest_dir)