目录
一、应用场景
当一个文件夹内有许多文件且,文件夹内又嵌套了多层文件夹和文件的情况下就增加了,人工把图片分开按照一定数量打包的工作繁琐程度,当文件夹内的文件和目录较多,且存在多级嵌套的关系时,显然人工处理就会变得异常艰难,甚至当数据量过大时,打开文件夹都会造成卡顿,在这样的情况下,利用python对文件分包就是比较好的解决方案。
二、需求分析
把一个压缩包里的目录及其子目录里的图片文件按照一定的数量,把图片每n张存放在一个文件夹内
三、编码过程
1、思路
(1)、创建一个目录,并把压缩包解压到这个目录下以压缩包名称命名的目录下(这里因为压缩包可能不止一个)
(2)、把遍历目录书写为一个函数(当遍历目录时当前目录的子目录下还有目录时可以调用函数避免了代码的繁琐),遍历当前目录,如果不是目录,判断是不是图片格式,如果是目录,调用当前函数对这个目录进行遍历
(3)、如果不是图片格式,那么就忽略,如果是图片格式,就把图片拷贝到分包目录并重命名,为每个包里的图片保存原始路径与拷贝后重命名的文件路径
2、代码
(1)、用到的类库
shutil:这里用于复制文件
OS:python内置库
concurrent:用于开启多进程(多进程没实际测试有没有用)
(2)、完整代码
from zipfile import ZipFile
import os
import shutil
import tqdm
from concurrent.futures import ThreadPoolExecutor
class ZipFiles():
def __init__(self):
self.file_count = 1
self.dir_count = 1
def unzipFiles(self,zip_list):
file_name = os.path.basename(zip_list)
folder_name = os.path.splitext(file_name)[0]
os.mkdir(f'./data/{folder_name}')
ZipFile(zip_list,'r').extractall(f'./data/{folder_name}')
files_name = f'./data/{folder_name}'
self.read_all_files(files_name,folder_name)
def read_all_files(self,files_Path,folder_name):
qwd_list = os.listdir(files_Path)
for i in tqdm.tqdm(qwd_list):
directoryName = files_Path+'/'+i
if os.path.isdir(directoryName): #file_Path是二级目录
self.read_all_files(directoryName,folder_name)
else:
fileExtension = os.path.splitext(i)
if fileExtension[1] == '.jpg' or fileExtension[1] == '.png':
img_Path = directoryName
self.subcontract(img_Path,folder_name)
def subcontract(self,img_Path, folder_name):
package_Path = f'./data/{folder_name}_sub'
if not os.path.exists(package_Path):
os.mkdir(package_Path)
newnames = package_Path+f'/xxxx_{folder_name[-2:]}_{str(self.dir_count).zfill(4)}_sub/xxxx_{folder_name[-2:]}_{str(self.file_count).zfill(6)}.jpg'
if self.file_count%20!=0:
if not os.path.exists(package_Path+f'/xxxx_{folder_name[-2:]}_{str(self.dir_count).zfill(4)}_sub'):
os.mkdir(package_Path + f'/xxxx_{folder_name[-2:]}_{str(self.dir_count).zfill(4)}_sub')
shutil.copyfile(img_Path, newnames)
self.file_count += 1
else:
shutil.copyfile(img_Path, newnames)
self.dir_count += 1
self.file_count += 1
with open(f'{package_Path}/pathDetails.txt','a') as f:
f.write(img_Path+'---'+newnames+'\n')
if __name__ == '__main__':
zip_list = ['./xxx.zip','./yyyy.zip']
if not os.path.exists('./data'):
os.mkdir('./data')
with ThreadPoolExecutor(20) as t:
for i in zip_list:
root = ZipFiles()
t.submit(root.unzipFiles(i))