There are a lot of tools for synchronizing folders, and here's a little script I wrote in Python, compatible with Windows and Linux, as a repetition of the invention of the wheel, but also as an exercise, hehe. The usage is simple, as follows:
Python syncdir.py source_dir Target_dir
The effect is to synchronize the files in the folder Source_dir to the folder Target_dir, and the synchronization process follows these rules:
1, if the file F1 in the Source_dir, and not in the Target_dir, the F1 will be copied to the Target_dir;
2, if the file F1 in Source_dir and Target_dir exist, but the last modification time or file size is not the same, then F1 from Source_dir to Target_dir, cover the original file in Target_dir.
As you can see, this rule is very simple and one-way, that is, only to ensure that the files in the Source_dir after synchronization are consistent in the Target_dir, but the Target_dir files will not reverse sync to source_dir.
The program code is as follows:
#-*-Coding:utf-8-*-# http://oldj.net/u "" Synchronized Two folder usage: Python syncdir.py source_dir after execution, the text in Target_dir The pieces will be synchronized to target_dir this synchronization is one-way, that is, only updates or new files in the Source_dir are copied to the Target_dir, if a file does not exist in Source_dir and exists in the Target_dir, this program will not delete the file And does not copy it to Source_dir. The way to determine whether a file is updated is to compare the file's last modification time with the consistent file size "" "Import OS import sys import shutil def errexit (msg): Prin T "-" * print "ERROR:" Print msg sys.exit (1) def main (Source_dir, target_dir): print "Synchronize '%s ' >> '% S ' ... '% (Source_dir, target_dir) print "=" * Sync_file_count = 0 Sync_file_size = 0 for root, dirs, files in OS.W ALK (source_dir): Relative_path = Root.replace (Source_dir, "") If Len (Relative_path) > 0 and Relative_path[0] in ("/ "," \ \ "): Relative_path = relative_path[1:] Dist_path = Os.path.join (Target_dir, Relative_path) if Os.path.isdir (d
Ist_path) = = False:os.makedirs (dist_path) Last_copy_folder = "" for fn0 in FILES:FN = Os.path.join (root, Fn0) FN2 = Os.path.join (dIst_path, fn0) is_copy = False if Os.path.isfile (fn2) = = False:is_copy = True Else:statinfo = Os.stat (f
N) Statinfo2 = Os.stat (fn2) is_copy = (Round (statinfo.st_mtime, 3)!= round (statinfo2.st_mtime, 3) \ or statinfo.st_size!= statinfo2.st_size) if is_copy:if dist_path!= last_copy_folder:print ' [%s] ' % Dist_path Last_copy_folder = dist_path print "Copying '%s ' ..."% fn0 shutil.copy2 (FN, fn2) Sync_file_c Ount + = 1 Sync_file_size + + + os.stat (FN). st_size if Sync_file_count > 0:print "-" * print "%d files synchro
nized! '% sync_file_count if sync_file_size > 0:print '%d bytes. '% sync_file_size print ' done! ' if __name__ = = "__main__": If Len (sys.argv)!= 3:if "-H" in sys.argv or "--help" in Sys.argv:print __doc__ sys.
Exit (1) errexit (U "Invalid arguments!") Source_dir, Target_dir = sys.argv[1:] If Os.path.isdir (source_dir) = = False:errexit (u "'%s ' not a folder!"% SOURCE_dir) elif os.path.isdir (target_dir) = = False:errexit (u "'%s ' is not a folder!"% target_dir) Main (Source_dir, Targe
T_dir)
Currently this version only supports synchronization under different folders in the local computer, and does not support remote network synchronization. During the writing of this script, I found that there are a few things to be aware of.
1. Under Windows, the first parameter of Os.path.join may not be what we want if it ends with ":". For example: Os.path.join ("D:", "tmp"), we may expect to get "d:\\tmp", but the actual result is "d:tmp", so you need to use Os.sep.join ("D:", "tmp").
2. The second parameter of Os.path.join if you start with "/" (If you start with "/" or "\" under Windows), the first argument is ignored. For example, Os.path.join ("tmp", "/test") will get the "/test".
3, Shutil.copy2 can copy the file to the designated place, it not only copies the contents of the file, but also the creation of the file time, the last modification time and other information together to handcuff the past.
3, with Os.stat (filename). St_mtime can take the last modification time of the specified file, which is a floating-point decimal. Files that are copied with the above shutil.copy2 may retain the last modification time of the file, but sometimes the last one or two digits of the decimal point can have errors due to floating-point accuracy. Therefore, after one synchronization, the st_mtime of the two identical files may be slightly inconsistent, so I used rounding in the script to retain only three digits after the decimal point of the last modification time (that is, to microseconds).