下面是关于在Linux下使用Python多线程递归复制文件夹及文件夹中的文件的攻略。具体步骤如下:
1. 导入必要的库
在 Python 里进行文件操作一般使用 os 和 shutil 这两个库。同时,由于涉及多线程操作,我们还需要使用 threading 和 queue 两个库。首先导入它们:
import os
import shutil
import threading
import queue
2. 定义一个复制文件夹的函数
在此之前,先定义一个检查文件夹是否存在的函数,以确保这篇攻略所使用的函数能够正确执行。
def ensure_dir(dir_path):
if not os.path.exists(dir_path):
os.makedirs(dir_path)
接下来定义复制文件夹的函数,这个函数会递归地复制文件夹及文件夹中的文件:
def copy_dir(source_dir, target_dir, file_queue):
ensure_dir(target_dir)
items = os.listdir(source_dir)
for item in items:
source = os.path.join(source_dir, item)
target = os.path.join(target_dir, item)
if os.path.isdir(source):
threading.Thread(target=copy_dir, args=(source, target, file_queue)).start()
else:
file_queue.put((source, target))
这个函数有三个参数:源文件夹(source_dir)、目标文件夹(target_dir)和文件队列(file_queue),其中文件队列是为了后面的多线程复制文件做准备。
具体流程如下:
首先,使用 ensure_dir()
函数创建目标文件夹。然后, 使用 os.listdir()
列出源文件夹中的所有文件和文件夹。接下来,对于每个文件或文件夹,使用 os.path.join()
组合出对应的源路径和目标路径。
如果这是一个文件夹,就回调 copy_dir()
函数,并新建一个子线程专门用于复制这个子文件夹。
否则,将这个文件的源路径和目标路径包含为一个元组,放入文件队列中。
3. 定义一个复制文件的函数
接下来,我们需要定义用于复制单个文件的函数。这个函数从文件队列中获取元组(源文件路径和目标文件路径),并复制文件:
def copy_file(file_queue):
while True:
try:
source, target = file_queue.get(timeout=1)
except queue.Empty:
break
ensure_dir(os.path.dirname(target))
shutil.copyfile(source, target)
这个函数有一个参数:文件队列(file_queue)。文件队列的作用是在多线程运行过程中,将要复制的文件按 FIFO(先进先出) 的方式压入队列,并由多个线程从队列中获取文件,进行复制操作。
关于多线程以及队列的相关用法,请参考 Python 程序员必备的库之一 threading 和 queue。
4. 启动多线程复制文件
现在我们已经定义好了复制文件夹和复制文件的函数,在主程序中,我们需要为它们创建多个线程,并将获得的文件元组放入队列中,随后由多个线程消费队列,以并发、并行地复制文件。
def main():
source_dir = '/path/to/source/dir'
target_dir = '/path/to/target/dir'
file_queue = queue.Queue()
threading.Thread(target=copy_dir, args=(source_dir, target_dir, file_queue)).start()
cp_threads = []
for i in range(4): # 创建 4 个线程用于复制文件
cp_thread = threading.Thread(target=copy_file, args=(file_queue,))
cp_threads.append(cp_thread)
cp_thread.start()
for cp_thread in cp_threads: # 等待所有线程完成
cp_thread.join()
在主程序中,首先配置源文件夹和目标文件夹的路径(source_dir 和 target_dir)。接着,创建一个文件队列,并将由 copy_dir()
函数获得的文件元组放入队列中,此时随之启动的是复制文件夹的线程。
然后创建四个线程用于处理文件,依次从文件队列中获取文件,并使用 copy_file()
函数来复制文件。最后,使用 join()
方法等待所有线程结束。
示例
下面给出两个调用示例:
示例一
如果你要复制的文件夹很大,想要加快复制效率,可以改变主程序的第 10 行,将 "4" 改成更大的数值:
for i in range(10): # 创建 10 个线程用于复制文件
cp_thread = threading.Thread(target=copy_file, args=(file_queue,))
cp_threads.append(cp_thread)
cp_thread.start()
示例二
有时候源文件夹中可能存在一些不需要复制的隐藏文件,这时可以对 copy_dir()
函数做一些改动,排除这些文件:
def copy_dir(source_dir, target_dir, file_queue):
ensure_dir(target_dir)
items = os.listdir(source_dir)
for item in items:
source = os.path.join(source_dir, item)
if item.startswith('.'): # 排除隐藏文件
continue
target = os.path.join(target_dir, item)
if os.path.isdir(source):
threading.Thread(target=copy_dir, args=(source, target, file_queue)).start()
else:
file_queue.put((source, target))
这里排除掉的是文件名以 "." 开头的隐藏文件。
希望这份攻略对于使用 Linux 下 Python 进行多线程文件复制有所帮助,如有问题欢迎提出!
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:linux 下python多线程递归复制文件夹及文件夹中的文件 - Python技术站