【问题标题】:Iterating through file sizes recursively递归地遍历文件大小
【发布时间】:2017-11-08 15:55:24
【问题描述】:

您好,我创建了一个小程序来获取脚本所在目录中所有文件的MD5 hash

我的问题是当我生成文件的get_size() 时,我的filelist.md5.txt 中只有一行,而get_size() 似乎正在输出整个目录的总和而不是每个单独的文件大小。 如何在此脚本中输出单个文件的大小?

我在filelist.md5.txt 文件中得到这个输出:

#
#  GENERATE_FILELIST
#  (filename)    (filesize)    (md5)    (major_version)    (minor_version)
#

Test_2.txt                                   190         dea9fe052f1abf71bac7421c732b0475      ----           ----

但是我想得到这个输出:

#
#  GENERATE_FILELIST
#  (filename)    (filesize)    (md5)    (major_version)    (minor_version)
#

MD5.bat                                      filesize              b9a7c825517002e0da8e980c2c2c2cef      ----           ----
MD5.py                                       filesize              b61124e8bef473d377f59aa0964174ce      ----           ----
MD5test.bat                                  filesize              f29d68f9721c57d648164cae79dac71b      ----           ----
MD5test.py                                   filesize              a7a3c45ebe1aca82f57591c7fccd6cfc      ----           ----
MD5v1.bat                                    filesize              e5e7407117845a2413fe667fe7a2f681      ----           ----
MD5v1.py                                     filesize              55ab90b5a623548825a0b40406fcdde2      ----           ----
MD5v2.bat                                    filesize              e9e31aaa62f6f37572cf89a03860cb96      ----           ----
MD5v3.bat                                    filesize              559c0e9ed05fc9b4884c83bc3e04f8fd      ----           ----
MD5v3.py                                     filesize              d20a8841f3c37d28fd3b74847731e212      ----           ----
Test_2.txt                                   filesize              dea9fe052f1abf71bac7421c732b0475      ----           ----

到目前为止的代码:

import glob
import hashlib
import sys
import os


filenames = glob.glob('*.*')

# truncate the file to zero length before opening
f1 = open(os.path.expanduser(sys.path[0]) + '\\filelist.md5.txt', 'w')

#'a' will append the file, rather than write over whatever else you put in it like 'w' 
with open('filelist.md5.txt', 'a') as f:
        print >> f,''
        print >> f,'#'
        print >> f,'#  GENERATE_FILELIST'
        print >> f,'#  (filename)    (filesize)    (md5)    (major_version)    (minor_version)'
        print >> f,'#'
        print >> f,''
f.close()

# print to console
for filename in filenames:
    with open(filename, 'rb') as inputfile:
        data = inputfile.read()
        print '. -- ',filename, ' ---------- ', hashlib.md5(data).hexdigest()

# get the size of each file
def get_size(start_path = '.'):
    total_size = 0
    for dirpath, dirnames, filenames in os.walk(start_path):
        for fn in filenames:
            fp = os.path.join(dirpath, fn)
            total_size += os.path.getsize(fp)
            return total_size

    #'a' will append the file, rather than write over whatever else you put in it like 'w'
with open('filelist.md5.txt', 'a') as f:

        print >> f,'{:44}'.format(filename), get_size(),'       ', hashlib.md5(data).hexdigest(),'    ','----','         ','----'

f.close()

【问题讨论】:

    标签: python windows for-loop md5


    【解决方案1】:

    您的get_size() 被写入返回整个目录的大小,这不是您要查找的内容。

    dir=r'specify\path\here'
    with open('filelist.md5.txt', 'w') as fx:
        for f in os.listdir(dir):
            path = os.path.join(dir, f)
            if os.path.isfile(path):
                # specify anything else you want to write inside fx.write()
                fx.write(f + "\t\t" + str(os.path.getsize(path)) + "\n")
    

    上面的代码用制表符分隔文件名和大小,并在单独的行中。

    你在做with open('filelist.md5.txt', 'a') as f:时不必显式关闭

    【讨论】:

    • 谢谢,当我将hashlib.md5(f).hexdigest() 添加到fx.write 时,我得到了奇怪的十六进制摘要......
    • @MALKAVIAN 没有看到您添加的内容和方式以及“奇怪”的结果,我无能为力。也许,您可以发布另一个问题。谢谢!
    【解决方案2】:

    试试这个(对于 larg_file、none_ascci_format_files_names、whitout glob 模块和 error_handling 效果更好):

    import hashlib, os, hashlib, sys
    
    your_target_folder = "."  # put your folder or just this "."
    
    
    def get_size(filename):
        st = os.stat(filename)
        return str(st.st_size)
    
    
    def get_minor_version(filename):
        # Your Code ...
        return "minor_version"
    
    
    def get_major_version(filename):
        # Your Code ...
        return "major_version"
    
    
    def get_md5(fname):
        hash_md5 = hashlib.md5()
        with open(fname, "rb") as f:
            for chunk in iter(lambda: f.read(2 ** 20), b""):
                hash_md5.update(chunk)
        return hash_md5.hexdigest()
    
    
    # this function works for none ascii files names ( like chinese format )!!
    def sys_out(out_data):
        try:
            print(out_data)
        except UnicodeEncodeError:
            if sys.version_info >= (3,):
                print(out_data.encode('utf8').decode(sys.stdout.encoding))
            else:
                print(out_data.encode('utf8'))
    
    
    def make_beautiful_terminal_output(get_list):
    
        col_width = max(len(word) for word in get_list) + 3  # padding
    
        buffer_last = []
        for row in get_list:
            buffer_last.append("".join(word.ljust(col_width) for word in get_list))
    
        return buffer_last[0]
    
    
    def print_header():
    
        header_tag = "(filename)                         (filesize)                         (md5)                             (major_version)                    (minor_version)\n"
    
        with open("filelist.md5.txt", "a") as my_header:
            my_header.write(header_tag)
    
        print(header_tag)
    
    
    print_header()
    
    for dirpath, _, filenames in os.walk(your_target_folder):
    
        for items in filenames:
            file_full_path = os.path.abspath(os.path.join(dirpath, items))
    
            try:
    
                my_last_data = [items, get_size(file_full_path), get_md5(file_full_path), get_major_version(file_full_path), get_minor_version(file_full_path)]
    
                terminal_output = make_beautiful_terminal_output(my_last_data)
    
                sys_out(terminal_output)
    
                re_buffer = terminal_output + "\n"
                with open("filelist.md5.txt", "a", encoding='utf-8') as my_save_file:
                    my_save_file.write(re_buffer)
    
            except:
                sys_out("Error On " + str(file_full_path))
    

    【讨论】:

    • 谢谢,唯一的问题是输出文件包含文字标题信息而不是值。顺便说一句,使用 python 2.7。
    • @MALKAVIAN:所以...您可以为这个答案投票 +1 吗?对于也想要这个答案的其他用户。
    • @MALKAVIAN:你知道赛通吗?
    • @MALKAVIAN:使用 cython,您可以将任何类型的 .py 文件转换为 c 或 c++ 代码!使用 jython 您可以将 .py 转换为 java 格式( .jar ),使用 kivy 您可以使用 python 制作 android 应用程序!使用 django,您可以使用 python 制作 Web 服务或网站!使用 pyqt 和 tkinter,您可以在 windows 和 unix 操作系统上制作 GUI 程序!使用 pyinstaller,您可以将 .py 文件编译为 .exe ....够了吗? python就是生命:))))
    猜你喜欢
    • 2012-06-16
    • 2016-03-12
    • 2011-03-21
    • 2018-07-24
    • 2018-07-12
    • 2014-03-11
    • 1970-01-01
    • 1970-01-01
    • 2014-11-12
    相关资源
    最近更新 更多