实验环境:linux系统、python3
实验过程:在工作目录下创建一个test文件夹,将实验文件拷贝其中;在工作目录下创建python文件,将以下代码拷贝其中。
实验分析:(包含在代码注释中)
代码使用者,若有觉得我分析理解不当之处,欢迎评论区指正;
# 导入所需模块
import os
import multiprocessing
# 定义copy方法,一开始要传入哪些参数,我们不能确定,唯一知道的只是一定要将遍历过的file_nam参数传进来
def copy_file(file_name, old_folder_name, new_folder_name):
"""完成文件的复制"""
# 通过print打印,模拟文件复制过程,让我们能直观的看到文件在复制。因此我们可以再传入两个参数old_folder_name、new_folder_name
print("====>模拟copy文件:从%s---->到%s 文件名是:%s" % (old_folder_name, new_folder_name, file_name))
"""
要想完成复制,首先要找到原文件并调用open函数以只读方式打开,再调用read函数将读取到的数据存入到
变量content中,最后调用close关闭文件
old_folder_name + "/" + file_name 是在拼原文件的路径,即可打开原文件读取内容
"""
old_f = open(old_folder_name + "/" + file_name, "rb")
content = old_f.read()
old_f.close()
"""
new_folder_name + "/" + file_name 是在创建一个同名文件,再通过open函数以只写的方式打开,之后
调用write函数将保存在变量content中的数据写入到同名文件中,实现文件复制。最后调用close关闭文件
"""
new_f = open(new_folder_name + "/" + file_name, "wb")
new_f.write(content)
new_f.close()
def main(): # 测试函数
# 获取用户要copy的文件夹的名字,将其赋值给变量 old_folder_name
old_folder_name = input("请输入要copy的文件夹的名字:")
# 创建新的文件夹,将获取来的文件夹名称与[复件]拼接,赋值给 new_folder_name
# 再调用os模块中mkdir方法创建一个新的文件夹
# 调用try....except.....的作用是,当该路径下已经存在此文件夹名称时,执行pass语句,不会因为重复创建而报错创建
# 简单来讲,已有该文件不进行创建,否则创建
try:
new_folder_name = old_folder_name + "[复件]"
os.mkdir(new_folder_name)
except:
pass
"""
到这里我们仅仅只是在工作路径下创建了一个空的复件文件夹而已,要想实现复制文件夹下的所有文件,
我们首先要先获取到文件夹下所有待copy的文件,才好进行copy操作。因此,调用os模块下的listdir()
方法可以以列表的形式获取到文件夹下的所有文件,并将其赋值给 file_names
"""
file_names = os.listdir(old_folder_name)
# print(file_names) 这里可以通过print打印查看
# 创建进程池 对象po
# 将进程参数设置为5,代表同时可以有五个进程,对提交来的任务文件进行copy处理
po = multiprocessing.Pool(5)
"""
将获取到的文件列表进行遍历
进程池po通过调用apply_async()方法,向进程池中的进程添加copy任务
apply_async()方法的第一个参数代表进程要执行的操作,这里既是copy文件的动作,copy_file应该写能实现copy文件动作的方法
写到这里,我们应该先去实现copy_file方法功能
方法实现之后,apply_async()方法第二个参数代表,可以向进程动作中传入的参数,即函数copy_file所需参数
"""
for file_name in file_names:
po.apply_async(copy_file, args=(file_name, old_folder_name, new_folder_name))
# 任务加载入进程池之后,关闭进程池
po.close()
# join()的作用是,进程池里的进程全部结束之后,主进程才能结束,在此之前主进程都要在这里堵塞着。
po.join()
if __name__ == "__main__":
main()
对案例添加显示进度条的理解和分析,在主页文章《进程池案例:多任务文件夹复制-显示进度条-理解和分析》解析