python实现自动计算目录下md5

python实现自动计算目录下md5




由于个人需求,准备实现一个py本实现遍历目录下所有文件并计算md5输出到列表中的需求。

1 基本思路

2 文件遍历

首先,我们需要先搞清楚python对文件的遍历操作,这里我们需要使用os库的listdir函数进行遍历,然后将文件输出到python的list对象中,代码如下:

def list_all_files(rootdir):
    import os
    _files = []
    list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
    for i in range(0,len(list)):
       path = os.path.join(rootdir,list[i])
       if os.path.isdir(path):
          _files.extend(list_all_files(path))
       if os.path.isfile(path):
           _files.append(path)
    return _files

这样,就可以通过以下代码获取目录下的所有文件:

list_all_files(root);

其中,root参数是要遍历的目录根路径。现在,我们需要将遍历到的文件进行md5计算,看如下代码:

def get_file_md5(file_path):
    if not os.path.isfile(file_path):
        return
    md5=hashlib.md5()
    f=file(file_path,'rb')
    if f:
        while True:
            b = f.read(8096)
            if not b:
                break
            md5.update(b)
        f.close()
    return md5.hexdigest()

一样,我们可以使用如下代码调用:

get_file_md5(filepath)

3 计算MD5

现在,还有个问题,我们可以通过list_all_files遍历目录,也可以通过get_file_md5计算md5,但是怎么写入文件?在这里,我们使用python的open方法,使用方式如下:

#打开文件
file = open(list_file,"w")
#写入文件
file.write(data)
#关闭文件
file.close

4 参数解析

我们的脚本是需要参数才能运行的,因此,还需要解决参数解析的问题,python本身可以通过sys对象获取参数,但这里,我们选择使用argparse进行参数解析,相关代码如下:

parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
args = parse.parse_args()

argparse的ArgumentParser方法有如下参数,含义如下:

参数 含义
prog 文件名,默认为sys.argv[0],用来在help信息中描述程序的名称。
usage 描述程序用途的字符串
description help信息前显示的信息
epilog help信息之后显示的信息
parents 由ArgumentParser对象组成的列表,它们的arguments选项会被包含到新ArgumentParser对象中。(类似于继承)
formatter_class help信息输出的格式,为了美观…
prefix_chars 参数前缀,默认为’-‘(最好不要修改)
fromfile_prefix_chars 前缀字符,放在文件名之前
conflict_handler 解决冲突的策略,默认情况下冲突会发生错误,(最好不要修改)
add_help 是否增加-h/-help选项 (默认为True),一般help信息都是必须的。设为False时,help信息里面不再显示-h –help信息
argument_default – (default: None)设置一个全局的选项的缺省值,一般每个选项单独设置,基本没用

接下来,我们需要了解下添加参数函数add_argument,它的调用格式是:
ArgumentParser.add_argument(name or flags...[, action][, nargs][, const][, default][, type][, choices][, required][, help][, metavar][, dest])
调用参数含义是:

参数 含义
argstring 参数有两种,可选参数和位置参数。
action 默认为store
metaver 帮助信息中显示的参数名称
nargs 参数的数量
const 保存一个常量
default 默认值
type 参数类型,默认为str
choices 设置参数值的范围,如果choices中的类型不是字符串,记得指定type
required 该选项是否必选,默认为True
dest 参数名

4.1 参数字符串

  参数格式有以下2种:

parser.add_argument('-f', '--foo')
parser.add_argument('bar')

这2种有不同的使用格式,第一种,则需要在使用以-或者–加参数名的形式 后面追加实参,另一种则直接在特定位置写参数即可,如:

# -f格式
./test.py -f XXX
或
./test.py --foo xxx
# 不带-格式
./test.py XXX

特定的参数会按指定的格式位置和形式,被自动解析。

4.2 行为方式

action参数决定了参数解析器解析到特定参数时的特定行为,分为如下类型:

action参数值 含义
store_const 值存放在const中
store_true和store_false 值存为True或False
append 存为列表,可以有多个参数
append_const 存为列表,会根据const关键参数进行添加
count 统计参数出现的次数
help 帮助信息
version 版本

4.3 解析参数

最后,我们需要调用parse_args函数进行解析,完整解析代码如下:

parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
parse.add_argument('-m','--match',dest='match',default='^.*$',nargs='?')
args = parse.parse_args()

使用时,只需要将脚本文件按如下方式调用:

./md5print.py /www tmp.txt # path = '/www',list_file='tmp.txt'

5 最后

写到最后,我想大家已经知道如何实现这个脚本了,以下是脚本的完整代码:

#!/usr/bin/python
# coding=utf-8

import argparse,sys,hashlib,os

parse = argparse.ArgumentParser()
parse.add_argument('path')
parse.add_argument('list_file')
parse.add_argument('-m','--match',dest='match',default='^.*$',nargs='?')
args = parse.parse_args()


def list_all_files(rootdir):
    import os
    _files = []
    list = os.listdir(rootdir) #列出文件夹下所有的目录与文件
    for i in range(0,len(list)):
       path = os.path.join(rootdir,list[i])
       if os.path.isdir(path):
          _files.extend(list_all_files(path))
       if os.path.isfile(path):
           _files.append(path)
    return _files


def get_file_md5(file_path):
    if not os.path.isfile(file_path):
        return
    md5=hashlib.md5()
    f=file(file_path,'rb')
    while True:
        b = f.read(8096)
        if not b:
            break
        md5.update(b)
    f.close()
    return md5.hexdigest()

def main():
    list = list_all_files(args.path)
    file = open(args.list_file,'w');
    if file:
        for filename in list:
            if re.match(args.match,filename) != None:
                md5 = get_file_md5(filename)
                file.write('%s|%s\n' % (md5,os.path.abspath(filename)))
        file.close()
if __name__ == '__main__':
    main()

6 参考

打赏

说点什么

avatar
  订阅  
提醒

扫码二维码快速访问本页

python实现自动计算目录下md5 – 起航天空