在Python中实现Windows两个服务器之间的文件夹同步,可以通过计算并对比文件的哈希值来判断文件是否被修改过。这里我们使用paramiko进行远程操作,并结合hashlib库计算MD5哈希值:
import os
import paramiko
import hashlib# 定义源与目标服务器信息
src_host = 'source_server_ip'
src_user = 'source_username'
src_password = 'source_password'
src_folder = '/path/to/source/folder'dst_host = 'destination_server_ip'
dst_user = 'destination_username'
dst_password = 'destination_password'
dst_folder = '/path/to/destination/folder'def calculate_md5(sftp, path):"""通过SFTP获取文件内容并计算MD5哈希"""md5_hash = hashlib.md5()with sftp.file(path, mode='rb') as f:while True:data = f.read(8192)if not data:breakmd5_hash.update(data)return md5_hash.hexdigest()def sync_files(sftp_src, src_path, sftp_dst, dst_path):# 遍历源目录下的所有项(文件或子目录)for src_name in sftp_src.listdir_attr(src_path):src_item_path = os.path.join(src_path, src_name.filename)dst_item_path = os.path.join(dst_path, src_name.filename)if S_ISDIR(src_name.st_mode): # 如果是目录if not sftp_dst.exists(dst_item_path): # 目录不存在于目标服务器,则创建sftp_dst.mkdir(dst_item_path)sync_files(sftp_src, src_item_path, sftp_dst, dst_item_path)else: # 是文件if not sftp_dst.exists(dst_item_path): # 文件不存在于目标服务器,直接上传sftp_dst.put(src_item_path, dst_item_path)else: # 文件存在时比较MD5哈希值src_file_md5 = calculate_md5(sftp_src, src_item_path)dst_file_md5 = calculate_md5(sftp_dst, dst_item_path)if src_file_md5 != dst_file_md5:# 哈希值不同,更新文件sftp_dst.remove(dst_item_path)sftp_dst.put(src_item_path, dst_item_path)# 处理源服务器上已删除但目标服务器上仍存在的文件for dst_name in sftp_dst.listdir_attr(dst_path):dst_item_path = os.path.join(dst_path, dst_name.filename)if not sftp_src.exists(os.path.join(src_path, dst_name.filename)):# 源服务器上不存在此文件,从目标服务器上删除sftp_dst.remove(dst_item_path)def main():ssh_src = paramiko.SSHClient()ssh_dst = paramiko.SSHClient()# 自动添加主机密钥到known_hostsssh_src.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh_dst.set_missing_host_key_policy(paramiko.AutoAddPolicy())ssh_src.connect(src_host, username=src_user, password=src_password)ssh_dst.connect(dst_host, username=dst_user, password=dst_password)sftp_src = ssh_src.open_sftp()sftp_dst = ssh_dst.open_sftp()sync_files(sftp_src, src_folder, sftp_dst, dst_folder)sftp_src.close()sftp_dst.close()ssh_src.close()ssh_dst.close()if __name__ == "__main__":main()
上述脚本首先定义了一个calculate_md5
函数用于计算给定路径下文件的MD5哈希值。在同步过程中,对于已存在的文件,通过比较源和目标服务器上的MD5哈希值来判断文件是否被修改,而不是仅依赖于文件大小和时间戳。同时,也处理了文件删除的情况。