Python编写的简易文件同步工具(已解决大文件同步时内存溢出问题)
个人工作时,会出现有两台或多台电脑需要同步一些文件的情况,但是因为公司文档的私密性,又不能上传网盘,就算有晖,但是一直开着检测目录变化的功能,又有点浪费电脑性能,所以就用python写了如下的小脚本,方便同步数据,因为系统占用很低,让它一直开着后台运行,也不至于影响工作,如果目标目录已有一样的文件也能很好的跳过,至于同步大文件时,内存泄漏问题,我也通过使用python的yield循环每次读取很小的部分(1024*8)解决了,还有因为有时文件比较多,一下同步不好,可以先中断,下次继续同步。废话不多说,看下面的的代码。
1.import os 
2.import hashlib 
3.import tkinter as tk 
4.from tkinter import messagebox 
5.import time 
6.import sys 
7.import keyboard 
8.import threading 
9. 
10.errmsg = "" 
11.dfilename = "" 
12.gotoBreak = False  xpath语法 python
13.stop_copying = False 
14.finishexit = False 
15. 
16.def chunked_file_Next_reader(file,block_size=1024 * 8):#分段读取比较的文件 
17.    while True: 
18.        global gotoBreak 
19.        if gotoBreak: 
20.            break 
21.        yield&ad(block_size) 
22. 
23.def copy_file(src, dst):#分段复制文件,可随时中断(stop_copying变量控制) 
24.    global stop_copying 
25.    with open(src, 'rb') as fs: 
26.        with open(dst, 'wb') as fd: 
27.            if stop_copying: 
28.                print("stoped"
29.            while not stop_copying: 
30.                buf =&ad(1024) 
31.                if not buf: 
32.                    break 
33.                fd.write(buf) 
34.            fd.close() 
35.        fs.close() 
36. 
37.def md5_diff(sfile,dfile):#比较函数 
38.    oldtime = time.time() 
39.    count = 0 
40.    scount = 0 
41.    k = True 
42.    with open(sfile,'rb') as sf: 
43.        with open(dfile,'rb') as df: 
44.            sdata = chunked_file_Next_reader(sf) 
45.            fdata = chunked_file_Next_reader(df) 
46.            while k: 
47.                s_nxtdata = next(sdata) 
48.                d_nxtdata = next(fdata) 
49.                count += 1 
50.                if s_nxtdata == b''
51.                    if d_nxtdata == b''
52.                        k = False 
53.                    else
54.                        count += 1 
55.                        break 
56.                else
57.                    s_md5 = hashlib.md5(s_nxtdata).hexdigest()#分段比较每段的hash值 
58.                    d_md5 = hashlib.md5(d_nxtdata).hexdigest() 
59.                    if s_md5 == d_md5: 
60.                        scount += 1         
61.                    else
62.                        #判断文件不一样 
63.                        sf.close() 
64.                        df.close() 
65.                        return 0 
66.            if (count - 1) == scount: 
67.                #判断文件一样 
68.                sf.close() 
69.                df.close() 
70.                return 1 
71.            else
72.                #判断文件不一样 
73.                sf.close() 
74.                df.close() 
75.                return 0 
76. 
77.def check_keyborad():#子线程判断退出操作(按q退出) 
78.    while True: 
79.        if keyboard.is_pressed("q"): 
80.            global errmsg 
81.            global gotoBreak 
82.            global stop_copying 
83.            gotoBreak = True#设置退出比较函数 
84.            stop_copying = True#设置退出复制函数 
85.            if errmsg == "": 
86.                errmsg = dfilename + " 处中断!"#设置断点断续的提示信息 
87.                print("error:" + errmsg) 
88.            with open(sys.path[0] + "\断点断续.txt",'w') as log:#把断点断续的位置写入与此脚本相同目录的"断点断续.txt" 
89.                log.write(errmsg) 
90.                log.close 
91.            messagebox.showinfo("提示",errmsg)#t弹出断点断续的提示信息窗口 
92.            it(0) 
93.        time.sleep(0.2) 
94.        if finishexit: 
95.            break 
96. 
97. 
98. 
99.def copyFile(spath,dpath):#判断复制主程序 
100.    global dfilename 
101.    for filename in os.listdir(spath): 
102.        if gotoBreak: 
103.            print("----------已中断-----------"
104.            break 
105. 
106.        sfilename = spath + os.sep + filename 
107.        dfilename = dpath + os.sep + filename 
108.        dfilename =&place('"''"',"")#替换掉拖到目标目录字符串中的引号 
109.        sfilename =&place('"',"")#替换掉拖到源目录字符串中的引号 
110.     
111.        if os.path.isdir(sfilename): 
112.            if not ists(dfilename): 
113.                os.mkdir(dfilename) 
114.            copyFile(sfilename,dfilename) 
115.        else
116.            global k 
117. 
118.            if dfilename == xpath and k == False:#判断输入的目录是否为空,进入断点断续程序 
119.                k = True 
120.                print("断点断续开始位置:" + dfilename) 
121.            if xpath == "" and k == False:#进入全新的同步进程 
122.                k = True 
123.                print("新开始:")     
124.            if k == True: 

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。