本文目录导读:

Python 实现(推荐)
基本双向同步
import os
import shutil
import filecmp
from datetime import datetime
def sync_folders(src_dir, dst_dir, sync_type='one_way'):
"""
文件夹同步功能
sync_type: 'one_way' 单向同步 (src -> dst)
'two_way' 双向同步
"""
if not os.path.exists(dst_dir):
os.makedirs(dst_dir)
# 获取源目录文件列表
for root, dirs, files in os.walk(src_dir):
# 计算相对路径
rel_path = os.path.relpath(root, src_dir)
dst_root = os.path.join(dst_dir, rel_path)
# 创建目标子目录
if not os.path.exists(dst_root):
os.makedirs(dst_root)
# 同步文件
for file in files:
src_file = os.path.join(root, file)
dst_file = os.path.join(dst_root, file)
# 检查是否需要同步
if not os.path.exists(dst_file) or \
os.path.getmtime(src_file) > os.path.getmtime(dst_file):
shutil.copy2(src_file, dst_file)
print(f"已同步: {src_file} -> {dst_file}")
# 如果是双向同步
if sync_type == 'two_way':
# 反向同步
for root, dirs, files in os.walk(dst_dir):
rel_path = os.path.relpath(root, dst_dir)
src_root = os.path.join(src_dir, rel_path)
for file in files:
dst_file = os.path.join(root, file)
src_file = os.path.join(src_root, file)
if not os.path.exists(src_file) or \
os.path.getmtime(dst_file) > os.path.getmtime(src_file):
if not os.path.exists(src_root):
os.makedirs(src_root)
shutil.copy2(dst_file, src_file)
print(f"已同步: {dst_file} -> {src_file}")
# 使用示例
sync_folders('/path/to/source', '/path/to/destination')
带监控的实时同步
import time
import hashlib
from watchdog.observers import Observer
from watchdog.events import FileSystemEventHandler
class SyncHandler(FileSystemEventHandler):
def __init__(self, src_dir, dst_dir):
self.src_dir = src_dir
self.dst_dir = dst_dir
self.last_modified = {}
def should_sync(self, file_path):
"""检查文件是否真的需要同步"""
current_mtime = os.path.getmtime(file_path)
file_hash = hashlib.md5(open(file_path, 'rb').read()).hexdigest()
if file_path in self.last_modified:
if self.last_modified[file_path] == file_hash:
return False
self.last_modified[file_path] = file_hash
return True
def on_modified(self, event):
if event.is_directory:
return
file_path = event.src_path
if not self.should_sync(file_path):
return
# 计算相对路径
rel_path = os.path.relpath(file_path, self.src_dir)
dst_path = os.path.join(self.dst_dir, rel_path)
# 确保目标目录存在
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
# 复制文件
shutil.copy2(file_path, dst_path)
print(f"实时同步: {file_path} -> {dst_path}")
def real_time_sync(src_dir, dst_dir):
"""实时文件夹同步"""
event_handler = SyncHandler(src_dir, dst_dir)
observer = Observer()
observer.schedule(event_handler, src_dir, recursive=True)
observer.start()
try:
while True:
time.sleep(1)
except KeyboardInterrupt:
observer.stop()
observer.join()
# 需要安装: pip install watchdog
# real_time_sync('/path/to/source', '/path/to/destination')
rsync 脚本 (Linux/Mac)
#!/bin/bash
# sync_folders.sh - 文件夹同步脚本
SOURCE_DIR="$1"
DEST_DIR="$2"
LOG_FILE="/var/log/folder_sync.log"
# 检查参数
if [ $# -lt 2 ]; then
echo "使用方法: $0 <源目录> <目标目录>"
exit 1
fi
# 同步功能
sync_folders() {
local src="$1"
local dst="$2"
echo "[$(date)] 开始同步: $src -> $dst" >> "$LOG_FILE"
# 使用 rsync 进行同步
rsync -avz --delete \
--progress \
--exclude=".DS_Store" \
--exclude="Thumbs.db" \
--exclude="node_modules/" \
--exclude=".git/" \
"$src/" "$dst/" 2>&1 | tee -a "$LOG_FILE"
echo "[$(date)] 同步完成" >> "$LOG_FILE"
}
# 执行同步
sync_folders "$SOURCE_DIR" "$DEST_DIR"
PowerShell 脚本 (Windows)
# sync_folders.ps1 - Windows文件夹同步脚本
param(
[Parameter(Mandatory=$true)]
[string]$Source,
[Parameter(Mandatory=$true)]
[string]$Destination,
[switch]$TwoWay,
[switch]$Log
)
function Sync-Folder {
param(
[string]$src,
[string]$dst,
[string]$direction
)
$logMessage = "[$(Get-Date)] 开始同步 $direction: $src -> $dst"
Write-Host $logMessage
# 使用 Robocopy 进行同步
$robocopyArgs = @(
$src,
$dst,
"/MIR", # 镜像模式
"/R:3", # 重试次数
"/W:5", # 等待时间
"/NP", # 不显示进度
"/NJH", # 不显示作业头
"/NJS" # 不显示作业摘要
)
if ($Log) {
$robocopyArgs += "/LOG+:sync_log.txt"
}
robocopy @robocopyArgs
# 双向同步
if ($TwoWay -and $direction -eq "源->目标") {
Sync-Folder -src $dst -dst $src -direction "目标->源"
}
}
# 执行同步
Sync-Folder -src $Source -dst $Destination -direction "源->目标"
使用 PyInotify (Linux 实时同步)
import pyinotify
import os
import shutil
class SyncWatcher(pyinotify.ProcessEvent):
def __init__(self, src_dir, dst_dir):
self.src_dir = src_dir
self.dst_dir = dst_dir
def process_IN_CREATE(self, event):
"""文件创建时同步"""
self.sync_file(event.pathname)
def process_IN_MODIFY(self, event):
"""文件修改时同步"""
self.sync_file(event.pathname)
def process_IN_DELETE(self, event):
"""文件删除时同步"""
rel_path = os.path.relpath(event.pathname, self.src_dir)
dst_path = os.path.join(self.dst_dir, rel_path)
if os.path.exists(dst_path):
os.remove(dst_path)
def sync_file(self, src_path):
rel_path = os.path.relpath(src_path, self.src_dir)
dst_path = os.path.join(self.dst_dir, rel_path)
os.makedirs(os.path.dirname(dst_path), exist_ok=True)
shutil.copy2(src_path, dst_path)
print(f"已同步: {src_path}")
def start_watcher(src_dir, dst_dir):
wm = pyinotify.WatchManager()
mask = pyinotify.IN_CREATE | pyinotify.IN_MODIFY | pyinotify.IN_DELETE
handler = SyncWatcher(src_dir, dst_dir)
notifier = pyinotify.Notifier(wm, handler)
wm.add_watch(src_dir, mask, rec=True, auto_add=True)
notifier.loop()
# 需要安装: pip install pyinotify
# start_watcher('/path/to/source', '/path/to/destination')
使用建议
| 场景 | 推荐方案 | 理由 |
|---|---|---|
| 一次性同步 | rsync/Python | 简单高效 |
| 实时同步 | watchdog/PyInotify | 自动监控变化 |
| Windows环境 | PowerShell | 原生支持 |
| 跨平台 | Python | 兼容性好 |
| 大文件同步 | rsync | 支持增量传输 |
安装依赖
# Python依赖 pip install watchdog # 实时监控 pip install pyinotify # Linux实时监控 # Linux工具 sudo apt-get install rsync # Ubuntu/Debian sudo yum install rsync # CentOS/RHEL
选择适合你需求的方案,建议先用基本版本测试,再根据需要进行扩展。