使用Python同步資料夾__Python

來源:互聯網
上載者:User

  同步資料夾的工具有很多,下面是我用 Python 寫的一個小指令碼,相容 Windows 和 Linux,算是重複發明輪子,不過也當是練習,呵呵。用法很簡單,如下:

  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 中。

  程式碼如下:

# -*- coding: utf-8 -*-# http://oldj.net/u"""同步兩個檔案夾用法:python syncdir.py source_dir target_dir執行後,source_dir 中的檔案將被同步到 target_dir 中這個同步是單向的,即只將 source_dir 中更新或新增的檔案拷到 target_dir 中,如果某個檔案在 source_dir 中不存在而在 target_dir 中存在,本程式不會刪除那個檔案,也不會將其拷貝到 source_dir 中判斷檔案是否更新的方法是比較檔案最後修改時間以及檔案大小是否一致"""import osimport sysimport shutildef errExit(msg):print "-" * 50print "ERROR:"print msgsys.exit(1)def main(source_dir, target_dir):print "synchronize '%s' >> '%s'..." % (source_dir, target_dir)print "=" * 50sync_file_count = 0sync_file_size = 0for 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 = Falseif os.path.isfile(fn2) == False:is_copy = Trueelse: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_pathlast_copy_folder = dist_pathprint "copying '%s' ..." % fn0shutil.copy2(fn, fn2)sync_file_count += 1sync_file_size += os.stat(fn).st_sizeif sync_file_count > 0:print "-" * 50print "%d files synchronized!" % sync_file_countif sync_file_size > 0:print "%d bytes." % sync_file_sizeprint "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 有可能會有微小的不一致,所以,指令碼中我用了四捨五入,只保留檔案最後修改時間小數點後的三位(即精確到微秒)。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.