pyhon--批量複製、移動文件或者文件夾

前沿:在之前的博客分享中,已經分享了 Python–使用線程–批量文件的移動 關於兩層文件的移動和複製,但是如果我們想多層的複製例如:D:\department_data_management 裏邊的而且包含很多曾文件夾,我們想原封不動的複製到F盤,此時怎麼搞?
今天就分享一下代碼,使用技術:線程+隊列。

# @Time    : 2019-04-11 09:59
# @Author  : xgp
# @File    : file_move.py
# @Software: PyCharm
# @description:把整個文件夾以及子文件夾複製到某個位置。
"""
waring:當你複製的文件比較少的時候,可能因爲文件夾只有一個線程在執行,而文件的複製是很多線程在執行,
這樣可能導致文件夾未建立而文件卻在複製而報錯,這個時候建議在執行一次即可。所以此方法適合複製大量的文件,或者文件夾。
"""

import os
import shutil
import threading
from queue import Queue


class FileMove:
    def __init__(self):
        """
        一些參數的輸入
        """
        self.folder_queue = Queue()
        self.file_queue = Queue()
        self.method = input('請選擇文件是選擇 複製 還是移動 ?eg:[複製,移動]:')
        self.file_path = input(r'請輸入想要操作的文件夾eg:[D:\Image]:')
        self.d_path = input(r'請輸入想要 移動\複製 到的盤符或者路徑eg:[E:, E:\image,F:,F:\image\picture]:')
        self.s_path = self.file_path[:2]

    def write_info(self, file_path):
        """
        向隊列中寫入文件夾和文件
        :param file_path: 
        :return: 
        """
        try:
            all_folder = os.listdir(file_path)
        except FileNotFoundError as e:
            print('請正確輸入文件夾的位置.......')
        else:
            for each_file in all_folder:
                if os.path.isdir(os.path.join(file_path, each_file)):
                    self.folder_queue.put(os.path.join(file_path, each_file))
                elif os.path.isfile(os.path.join(file_path, each_file)):
                    self.file_queue.put(os.path.join(file_path, each_file))

    def read_folder(self):
        """
        獲取到文件夾,並在目的盤 建立文件夾,如果文件夾中還含有文件夾和文件 調用 write_info 方法繼續寫。
        :return: 
        """
        while True:
            try:
                folder_path = self.folder_queue.get(timeout=3)
                self.folder_queue.task_done()
            except BaseException as e:
                print('文件夾的獲取結束,開始下一個階段文件的複製............... %s' % str(e))
                break
            else:
                try:
                    if not os.path.exists(folder_path.replace(self.file_path, self.d_path)):
                        os.makedirs(folder_path.replace(self.file_path, self.d_path))
                except BaseException as e:
                    print('創建文件夾的時候出現了問題 %s' % str(e))
            self.write_info(folder_path)

    def read_file(self):
        """
        從file隊列中拿到文件 並進行復制或者移動。
        :return: 
        """
        while True:
            try:
                file_path = self.file_queue.get(timeout=3)
                self.file_queue.task_done()
            except BaseException as e:
                print('獲取文件結束,整個流程走完.........終止 %s' % str(e))
                break
            else:
                try:
                    if not os.path.exists(file_path.replace(self.file_path, self.d_path)):  # 這個是你需要修改的
                        if self.method == "複製":
                            print('複製中..........')
                            shutil.copy(file_path, file_path.replace(self.file_path, self.d_path))
                        elif self.method == "移動":
                            print('移動中.........')
                            shutil.move(file_path, file_path.replace(self.file_path, self.d_path))
                            shutil.rmtree(self.file_path)
                        else:
                            print('暫未開放此功能........敬請期待')
                            break
                    else:
                        print('已經存在了')
                        pass
                except BaseException as e:
                    print('複製文件的時候出錯了...............%s' % str(e))

    def run(self):
        """
        主邏輯開始運行。
        :return: 
        """
        thread_list = []
        info_list = threading.Thread(target=self.write_info, args=(self.file_path,))
        thread_list.append(info_list)
        folder_list = threading.Thread(target=self.read_folder)
        thread_list.append(folder_list)
        for i in range(50):
            file_list = threading.Thread(target=self.read_file)
            thread_list.append(file_list)
        for t in thread_list:
            t.setDaemon(True)
            t.start()
        for q in [self.folder_queue, self.file_queue]:
            q.join()
        print('結束')


if __name__ == '__main__':
    file_move = FileMove()
    file_move.run()

這只是一個簡單的 複製 和移動,你也可以在源代碼的基礎上進行修改和添加,使其功能更強,當然你也可以打包一下分享給你的朋友使用,如果運行代碼中出現一點小bug自行解決或者一起討論。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章