一、解压rar
非Windows环境对.rar文件兼容不是很好,不建议使用,会出现奇奇怪怪的问题,如果一定要用,如下:
1、安装rarfile
pip install rarfile
2、简单的例子
import rarfile
import datetime
path = "../files/test.rar"
path2 = "../files/"
print(datetime.datetime.now())
rf = rarfile.RarFile(path)
print(rf.namelist())
print(len(rf.namelist()))
rf.extractall(path2)
print(datetime.datetime.now())
二、解压zip包
在使用过程中发现,window环境和非window环境打包出来的zip包,会有编码不一致问题,特殊是压缩包内有中文名的文件时,会出现乱码,需要做一下特殊处理。
1、安装
pip install zipstream
2、工具类
import zipfile
import os
import zipstream
import datetime
import traceback
from utils.exception_util import MyException
class ZipUtil(object):
zip_file = None
def __init__(self):
self.zip_file = zipstream.ZipFile(mode='w', compression=zipstream.ZIP_DEFLATED)
def to_zip(self, file, name):
if os.path.isfile(file):
self.zip_file.write(file, arcname=os.path.basename(file))
else:
self.add_folder_to_zip(file, name)
def add_folder_to_zip(self, folder, name):
for file in os.listdir(folder):
full_path = os.path.join(folder, file)
if os.path.isfile(full_path):
self.zip_file.write(full_path, arcname=os.path.join(name, os.path.basename(full_path)))
elif os.path.isdir(full_path):
self.add_folder_to_zip(full_path, os.path.join(name, os.path.basename(full_path)))
def close(self):
if self.zip_file:
self.zip_file.close()
def unzip_file(self, zip_src, dst_dir):
file_name_list = []
try:
r = zipfile.is_zipfile(zip_src)
if r:
with zipfile.ZipFile(zip_src, 'r') as fz:
for name in fz.namelist():
fz.extract(name, dst_dir)
old_path = os.path.join(dst_dir, name)
# 解决中文乱码问题,兼容window、ma压缩的zip包
try:
new_name = name.encode('cp437').decode('utf-8')
except Exception as e:
new_name = name.encode('cp437').decode('gbk')
new_path = os.path.join(dst_dir, new_name)
# 重命名文件
os.rename(old_path, new_path)
if '_MACOSX' not in new_path:
file_name_list.append(new_path)
return file_name_list
else:
raise MyException(code=5001, msg='Upload file is not a zip.')
except MyException as e:
raise e
except Exception as e:
raise MyException(code=5002, msg="Unzip file failed.")
finally:
self.close()
if __name__ == "__main__":
pass