首頁 >後端開發 >Python教學 >使用 Python 同步兩個目錄之間的文件

使用 Python 同步兩個目錄之間的文件

王林
王林原創
2024-08-16 18:01:091145瀏覽

Synchronizing Files Between Two Directories Using Python

在目錄之間同步檔案是管理備份、確保跨多個儲存位置的一致性或簡單地保持資料有序的常見任務。

雖然有許多工具可用於執行此操作,但建立 Python 腳本來處理目錄同步可提供靈活性和控制力。

本指南將引導您完成一個旨在同步兩個目錄之間的檔案的 Python 腳本。


腳本簡介

此腳本首先匯入幾個基本的 Python 函式庫。

其中包含用於與作業系統互動的os、用於進階檔案操作的shutdown、用於比較檔案的filecmp、用於解析命令列參數的argparse 以及用於在長時間操作期間顯示進度條的tqdm 。

這些函式庫協同工作,為目錄同步創建強大的解決方案。

import os
import shutil
import filecmp
import argparse
from tqdm import tqdm

腳本主要使用Python內建模組,但進度條使用tqdmlibrary,需要安裝:

pip install tqdm

檢查和準備目錄

開始同步之前,腳本需要檢查來源目錄是否存在。

如果目標目錄不存在,腳本將建立它。

此步驟非常重要,可以確保同步過程順利運行,不會出現因遺失目錄而導致的任何問題。

# Function to check if the source and destination directories exist
def check_directories(src_dir, dst_dir):
    # Check if the source directory exists
    if not os.path.exists(src_dir):
        print(f"\nSource directory '{src_dir}' does not exist.")
        return False
    # Create the destination directory if it does not exist
    if not os.path.exists(dst_dir):
        os.makedirs(dst_dir)
        print(f"\nDestination directory '{dst_dir}' created.")
    return True

check_directories 函數確保來源目錄和目標目錄都已準備好同步。其工作原理如下:

  • 函數使用 os.path.exists() 檢查目錄是否存在。
  • 如果來源目錄遺失,腳本會告訴使用者並停止執行。
  • 如果目標目錄遺失,腳本會使用 os.makedirs() 自動建立它。這可確保必要的目錄結構就位。

在目錄之間同步文件

此腳本的主要工作是同步來源目錄和目標目錄之間的檔案。

sync_directories 函數透過先遍歷來源目錄來收集所有檔案和子目錄的清單來處理此任務。

os.walk 函數透過在目錄樹中產生檔案名稱來提供協助,允許腳本擷取來源目錄中的每個檔案和資料夾。

# Function to synchronize files between two directories
def sync_directories(src_dir, dst_dir, delete=False):
    # Get a list of all files and directories in the source directory
    files_to_sync = []
    for root, dirs, files in os.walk(src_dir):
        for directory in dirs:
            files_to_sync.append(os.path.join(root, directory))
        for file in files:
            files_to_sync.append(os.path.join(root, file))

    # Iterate over each file in the source directory with a progress bar
    with tqdm(total=len(files_to_sync), desc="Syncing files", unit="file") as pbar:
        # Iterate over each file in the source directory
        for source_path in files_to_sync:
            # Get the corresponding path in the replica directory
            replica_path = os.path.join(dst_dir, os.path.relpath(source_path, src_dir))

            # Check if path is a directory and create it in the replica directory if it does not exist
            if os.path.isdir(source_path):
                if not os.path.exists(replica_path):
                    os.makedirs(replica_path)
            # Copy all files from the source directory to the replica directory
            else:
                # Check if the file exists in the replica directory and if it is different from the source file
                if not os.path.exists(replica_path) or not filecmp.cmp(source_path, replica_path, shallow=False):
                    # Set the description of the progress bar and print the file being copied
                    pbar.set_description(f"Processing '{source_path}'")
                    print(f"\nCopying {source_path} to {replica_path}")

                    # Copy the file from the source directory to the replica directory
                    shutil.copy2(source_path, replica_path)

            # Update the progress bar
            pbar.update(1)

編譯檔案和目錄清單後,腳本將使用 tqdm 提供的進度條向使用者提供有關同步過程的回饋。

對於來源中的每個檔案和目錄,腳本計算目標中對應的路徑。

如果路徑是目錄,腳本將確保它存在於目標中。

如果路徑是文件,腳本會檢查目標文件中是否已存在該文件以及它是否與原始文件相同。

如果檔案遺失或不同,腳本會將其複製到目標位置。

這樣,腳本就可以讓目標目錄與來源目錄保持最新。


清理多餘的文件

此腳本還有一個選用功能,可以刪除目標目錄中不在來源目錄中的檔案。

這是由使用者可以設定的 --delete 標誌控制的。

如果使用此標誌,腳本將遍歷目標目錄並將每個檔案和資料夾與來源進行比較。

如果在目標中發現來源中沒有的任何內容,則腳本會將其刪除。

這可確保目標目錄是來源目錄的精確副本。

# Clean up files in the destination directory that are not in the source directory, if delete flag is set
    if delete:
        # Get a list of all files in the destination directory
        files_to_delete = []
        for root, dirs, files in os.walk(dst_dir):
            for directory in dirs:
                files_to_delete.append(os.path.join(root, directory))
            for file in files:
                files_to_delete.append(os.path.join(root, file))

        # Iterate over each file in the destination directory with a progress bar
        with tqdm(total=len(files_to_delete), desc="Deleting files", unit="file") as pbar:
            # Iterate over each file in the destination directory
            for replica_path in files_to_delete:
                # Check if the file exists in the source directory
                source_path = os.path.join(src_dir, os.path.relpath(replica_path, dst_dir))
                if not os.path.exists(source_path):
                    # Set the description of the progress bar
                    pbar.set_description(f"Processing '{replica_path}'")
                    print(f"\nDeleting {replica_path}")

                    # Check if the path is a directory and remove it
                    if os.path.isdir(replica_path):
                        shutil.rmtree(replica_path)
                    else:
                        # Remove the file from the destination directory
                        os.remove(replica_path)

                # Update the progress bar
                pbar.update(1)

這部分腳本使用與同步過程類似的技術。

它使用 os.walk() 來收集檔案和目錄,並使用 tqdm 來顯示進度。
Shutil.rmtree() 函數用於刪除目錄,而 os.remove() 則處理單一檔案。


運行腳本

此腳本設計為從命令列運行,參數指定來源目錄和目標目錄。

argparse 模組可以輕鬆處理這些參數,讓使用者在執行腳本時簡單地提供必要的路徑和選項。

# Main function to parse command line arguments and synchronize directories
if __name__ == "__main__":
    # Parse command line arguments
    parser = argparse.ArgumentParser(description="Synchronize files between two directories.")
    parser.add_argument("source_directory", help="The source directory to synchronize from.")
    parser.add_argument("destination_directory", help="The destination directory to synchronize to.")
    parser.add_argument("-d", "--delete", action="store_true",
                        help="Delete files in destination that are not in source.")
    args = parser.parse_args()

    # If the delete flag is set, print a warning message
    if args.delete:
        print("\nExtraneous files in the destination will be deleted.")

    # Check the source and destination directories
    if not check_directories(args.source_directory, args.destination_directory):
        exit(1)

    # Synchronize the directories
    sync_directories(args.source_directory, args.destination_directory, args.delete)
    print("\nSynchronization complete.")

主要功能將所有內容整合在一起。

它處理命令列參數,檢查目錄,然後執行同步。

如果設定了 --delete 標誌,它還會處理額外檔案的清理。


範例

讓我們來看一些如何使用不同選項來執行腳本的範例。

出發地到目的地

python file_sync.py d:\sync d:\sync_copy 
Destination directory 'd:\sync2' created.
Processing 'd:\sync\video.mp4':   0%|                                                                                                   | 0/5 [00:00<?, ?file/s]
Copying d:\sync\video.mp4 to d:\sync2\video.mp4
Processing 'd:\sync\video_final.mp4':  20%|██████████████████▌                                                                          | 1/5 [00:00<?, ?file/s] 
Copying d:\sync\video_final.mp4 to d:\sync2\video_final.mp4
Processing 'd:\sync\video_single - Copy (2).mp4':  40%|████████████████████████████████▍                                                | 2/5 [00:00<?, ?file/s] 
Copying d:\sync\video_single - Copy (2).mp4 to d:\sync2\video_single - Copy (2).mp4
Processing 'd:\sync\video_single - Copy.mp4':  60%|█████████████████████████████████████████████▌                              | 3/5 [00:00<00:00, 205.83file/s]
Copying d:\sync\video_single - Copy.mp4 to d:\sync2\video_single - Copy.mp4
Processing 'd:\sync\video_single.mp4':  80%|██████████████████████████████████████████████████████████████████▍                | 4/5 [00:00<00:00, 274.44file/s] 
Copying d:\sync\video_single.mp4 to d:\sync2\video_single.mp4
Processing 'd:\sync\video_single.mp4': 100%|███████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 343.05file/s] 

Synchronization complete.

Source to Destination with Cleanup of Extra Files

python file_sync.py d:\sync d:\sync_copy -d
Extraneous files in the destination will be deleted.
Syncing files: 100%|████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<00:00, 63.29file/s]
Deleting files: 100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 5/5 [00:00<?, ?file/s] 

Synchronization complete.

Conclusion

This Python script offers a powerful and flexible way to synchronize files between two directories.

It uses key libraries like os, shutil, and filecmp, and enhances the user experience with tqdm for tracking progress.

This ensures that your data is consistently and efficiently synchronized.
Whether you're maintaining backups or ensuring consistency across storage locations, this script can be a valuable tool in your toolkit.

以上是使用 Python 同步兩個目錄之間的文件的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn