一个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 是表示获取当前路径下这些子目录的所有文件。可以根据自己项目的情况,自己修改。
posted @ 2017-03-28 17:23  bigasa  阅读(2180)  评论(0编辑  收藏  举报