#!/usr/bin/env python3
import os
import hashlib
import argparse
from pathlib import Path

def calculate_md5(file_path):
    """计算文件的MD5值"""
    md5_hash = hashlib.md5()
    with open(file_path, "rb") as f:
        # 分块读取文件,避免大文件导致内存问题
        for chunk in iter(lambda: f.read(4096), b""):
            md5_hash.update(chunk)
    return md5_hash.hexdigest()

def find_all_files(directory):
    """查找目录中所有文件"""
    results = []
    for root, _, files in os.walk(directory):
        for file in files:
            full_path = os.path.join(root, file)
            results.append(full_path)
    return results

def main():
    parser = argparse.ArgumentParser(description='计算指定目录下所有文件的MD5值')
    parser.add_argument('directory', nargs='?', default="", 
                      help='要扫描的目录路径(默认为当前目录)')
    parser.add_argument('-o', '--output',default="", help='输出结果到文件')
    
    args = parser.parse_args()
    
    # 确保目录存在
    if not os.path.exists(args.directory):
        print(f"错误:目录 '{args.directory}' 不存在")
        return

    # 查找所有文件
    all_files = find_all_files(args.directory)
    
    if not all_files:
        print(f"在 '{args.directory}' 中没有找到任何文件")
        return

    # 计算并存储结果
    results = []
    for file_path in all_files:
        try:
            md5 = calculate_md5(file_path)
            relative_path = os.path.relpath(file_path, args.directory)
            results.append((relative_path, md5))
            print(f"处理: {relative_path}")
        except Exception as e:
            print(f"处理文件 '{file_path}' 时出错: {e}")

    # 输出结果
    output_content = "\n=== MD5计算结果 ===\n"
    for file_path, md5 in sorted(results):
        output_content += f"{file_path}: {md5}\n"

    print(output_content)

    # 如果指定了输出文件,将结果写入文件
    if args.output:
        try:
            with open(args.output, 'w', encoding='utf-8') as f:
                f.write(output_content)
            print(f"\n结果已保存到: {args.output}")
        except Exception as e:
            print(f"写入输出文件时出错: {e}")

if __name__ == "__main__":
    main()