Python基础教程之同步文件夹

发布时间:2019-11-25编辑:脚本学堂
本文介绍了python同步文件夹的方法,php基础教程实例之同步文件夹的例子,有需要的朋友参考下。

例子,python基础教程实例之怎么同步文件夹?
用法很简单,如下:
python syncdir.py source_dir target_dir
将文件夹 source_dir 中的文件同步到文件夹 target_dir 中,同步的过程遵循以下规则:
1、如果文件 f1 在 source_dir 中存在,且不在 target_dir 中,则将 f1 拷到 target_dir 中;
2、如果文件 f1 在 source_dir 与 target_dir 中都存在,但最后修改时间不一样或文件大小不一样,则将 f1 从 source_dir 拷到 target_dir 中,覆盖 target_dir 中的原文件。
规则非常简单,而且是单向的,即只保证同步之后 source_dir 中的文件在 target_dir 中保持一致,但 target_dir 中独有的文件不会反向同步到 source_dir 中。

代码:
 

复制代码 代码示例:
#!/usr/bin/python
# www.jb200.com
# -*- coding: utf-8 -*-
import os
import sys
import shutil
 
def errExit(msg):
    print "-" * 50
    print "ERROR:"
    print msg
    sys.exit(1)
 
def main(source_dir, target_dir):
    print "synchronize '%s' >> '%s'..." % (source_dir, target_dir)
    print "=" * 50
    sync_file_count = 0
    sync_file_size = 0
 
    for root, dirs, files in os.walk(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(dist_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(fn)
                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_count += 1
                sync_file_size += os.stat(fn).st_size
 
    if sync_file_count > 0:
        print "-" * 50
    print "%d files synchronized!" % 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' is not a folder!" % source_dir)
    elif os.path.isdir(target_dir) == False:
        errExit(u"'%s' is not a folder!" % target_dir)
 
    main(source_dir, target_dir)

代码说明:
目前这个版本只支持本机不同文件夹下的同步,不支持远程网络同步。

几点注意事项:

  1、在 Windows 下,os.path.join 的第一个参数如果以“:”结尾,得到的结果可能不是想要的。比如:os.path.join(“D:”, “tmp”),可能会预期得到 “D:tmp” ,但实际得到的是 “D:tmp” ,所以这样的情况下需要使用 os.sep.join(“D:”, “tmp”) 。

  2、os.path.join 的第二个参数如果以“/”开头(Windows 下如果以“/”或“”开头),则第一个参数将被忽略。比如 os.path.join(“tmp”, “/test”) 得到的将是 “/test” 。

  3、shutil.copy2 可以将文件拷贝到指定地方,它不仅拷贝文件内容,同时还会把文件的创建时间、最后修改时间等信息一起拷过去。

  3、用 os.stat(filename).st_mtime 可以取到指定文件的最后修改时间,这个时间是一个浮点小数。用上面的 shutil.copy2 拷贝的文件虽然能保留文件的最后修改时间,但有时由于浮点精度的问题,可能在小数的最后一两位会有误差。因此,一次同步过后,两个相同文件的 st_mtime 有可能会有微小的不一致,所以,脚本中用了四舍五入,只保留文件最后修改时间小数点后的三位(即精确到微秒)。