該方法通用性更廣,可以將文件夾下的子文件夾中的數據也都壓縮。
- 先遍歷獲取所有的文件
- 創建一個壓縮文件,將1中所有文件壓縮進去
- 在壓縮的時候注意壓縮文件中的名稱要包含目錄,即壓縮文件中的文件名arcname= file.replace(fold_path,’’).lstrip(’/’)
import zipfile
import glob,os,time,shutil
def ZipFoldWithChildren(fold_path,is_remove=True):
'''
fold_path:要壓縮的文件夾
is_remove:壓縮後是否要把源文件刪除,默認是刪除的
'''
t0 = time.time()
# 判斷壓縮文件是否存在
fold_path = fold_path.replace('\\','/')
zipfiles = glob.glob(fold_path+'*.zip')
if len(zipfiles) >0:
zipfilename = fold_path + '-{}.zip'.format(len(zipfiles))
else:
zipfilename = fold_path + '.zip'
files = []
for root,fold,filenames in os.walk(fold_path):
root = root.replace('\\','/')
if len(filenames)>0:
tmp_files = ['/'.join([root,filename]) for filename in filenames]
files.extend(tmp_files)
badfiles = []
isuccess = 0
ifail = 0
with zipfile.ZipFile(zipfilename, 'w') as z:
for file in set(files):
try:
zip_name = file.replace(fold_path,'').lstrip('/')
z.write(file, arcname=zip_name, compress_type=zipfile.ZIP_DEFLATED)
isuccess += 1
if is_remove:
os.remove(file)
except:
badfiles.append(file)
ifail += 1
# 如果文件都被壓縮了,並且源文件都被刪除了,那麼這個空文件夾也就沒存在的意義了,故刪除
if len(badfiles)==0 and is_remove:# len 比 not badfiles更好理解
shutil.rmtree(fold_path)
print(f'文件夾{fold_path}壓縮成功,共壓縮文件成功{isuccess}個,失敗{ifail}個')
print('耗時{:.2f}s'.format(time.time()-t0))
return badfiles