一个python的文件对比脚本
脚本主要用来给游戏客户端做热更的。
处理方式就是针对每个文件求其MD5值,再根据文件的目录和名字对比两个版本的MD5值,如果不一样,则这次热更就需要更新这个文件。
用法很简单。
1,生成MD5码列表
参数有-i,针对某个目录下的指定路径下的所有文件生成MD5的列表。-v 当前版本号多少
2,对比两个路径的文件,并且将不同MD5的文件输出到指定路径下。
参数有-l,-r,-o.
-l就是左边的文件,为比较旧版本的目录。
-r就是右边的文件,为最新版本的目录。
-o就是不同文件的输出目录。
对比会优先查找左边文件夹下是否有.md5,如果有的话,会优先使用文件里的md5记录。
import sys, getopt import os import os.path import hashlib import shutil searchFolders = ["\\src\\", "\\res\\"] def usage(): print "this is useage" def getmd5(filename, parentName, folderName): m = hashlib.md5() mfile = open(filename, 'rb') m.update(mfile.read()) mfile.close() md5value = m.hexdigest() #get last part of file name subStr = filename[len(parentName) - len(folderName):len(filename)] return md5value+"\t"+ subStr def getCurDir(): path = sys.path[0] if os.path.isdir(path): return path elif os.path.isfile(path): return os.path.dirname(path) def saveFile(str, ver): f = open(getCurDir() + "/" + ver + ".md5", 'w') f.write(str) f.close() def getDescOfUrl(url): saveStr = "" descList = [] index = 0 for parent,dirnames,filenames in os.walk(url): for filename in filenames: for i, val in enumerate(searchFolders): targParent = url + val if targParent in parent: fullPath = os.path.join(parent, filename) md5 = getmd5(fullPath, targParent, val) #print "file is: " + md5 saveStr = saveStr + md5 + "\n" descList.append(md5) return saveStr, descList def onIArg(url, ver): saveStr, descList = getDescOfUrl(url) saveFile(saveStr, ver) def getDicByFile(url): file = open(url) line = f.readline() retDic = {} while line: md5, filename = line.split("\t") retDic[filename] = md5 return retDic def getDicByUrl(url): saveStr, splitArr = getDescOfUrl(url) retDic = {} for value in splitArr: md5, filename = value.split("\t") retDic[filename] = md5 return retDic def getDicOfUrl(url): fileList = os.listdir(url) version = "" for value in fileList: if os.path.splitext(value)[1] == '.md5': version = os.path.splitext(value)[0] break if version != "": return getDicByFile(url + "/" + version + ".md5") else: return getDicByUrl(url) opts,args = getopt.getopt(sys.argv[1:], "hi:l:r:v:o:") inputFile = "" leftFile = "" rightFile = "" outFile = "" version = "" showHelp = False for op, value in opts: if op == "-i": inputFile = value elif op == "-v": version = value elif op == "-l": leftFile = value elif op == "-r": rightFile = value elif op == "-o": outFile = value elif op == "-h": showHelp = True if showHelp: usage() sys.exit() elif inputFile != "": if version == "": print "you must input the version value using -v" sys.exit() onIArg(inputFile, version) elif leftFile != "": if rightFile == "": print "you must input the right file url using -r" sys.exit() elif outFile == "": print "you must input the out direct using -o" sys.exit() else: print "on diff .." diffDic = {} leftDic = getDicOfUrl(leftFile) rightDic = getDicOfUrl(rightFile) for (filename, md5) in rightDic.items(): if not leftDic.has_key(filename): diffDic[filename] = True elif leftDic.get(filename) != md5: diffDic[filename] = True for (filename, val) in diffDic.items(): #if the folder exit inUrl = rightFile + filename outUrl = outFile + filename folderIndex = outUrl.rfind("\\") outFolder = outUrl[0:folderIndex] if not os.path.isdir(outFolder): os.makedirs(outFolder) print("copy from " + rightFile + filename) print("to " + outUrl) shutil.copy(inUrl, outUrl)
脚本里的
searchFolders 是表示获取当前路径下这些子目录的所有文件。可以根据自己项目的情况,自己修改。