Python检查与分析磁盘空间使用情况并生成报告

Written by

in

文章目录
  • 磁盘空间管理是系统维护中的重要环节。随着数据的不断增长,磁盘空间可能会逐渐被占满,导致系统性能下降甚至崩溃。定期检查和分析磁盘空间使用情况,可以帮助我们及时发现空间不足的问题,并采取相应的措施。本文将介绍一个实用的Python脚本——磁盘空间使用报告工具,它可以生成详细的磁盘空间使用报告,帮助用户了解磁盘空间的分布情况。
  • 这个磁盘空间使用报告工具具有以下核心功能: 磁盘信息获取:获取系统中所有磁盘分区的总空间、已用空间和可用空间 目录大小分析:深入分析指定目录下各子目录和文件的大小分布 可视化报告:生成直观的饼图和柱状图展示磁盘空间使用情况 详细统计信息:提供文件数量、目录数量、最大文件等统计信息 多格式输出:支持文本报告、JSON数据和图表等多种输出格式 过滤功能:可以根据文件类型、大小等条件过滤分析结果 定时任务支持:可以集成到定时任务中定期生成报告 跨平台兼容:支持Windows、Linux和macOS操作系统
  • 这个工具适用于以下场景: 系统维护:定期检查服务器磁盘空间使用情况 存储优化:识别占用空间较大的目录和文件 容量规划:根据历史数据预测存储需求 故障排查:定位磁盘空间不足的原因 资源审计:审计系统中的大文件和无用文件 备份管理:分析备份目录的空间使用情况
  • 脚本包含了完善的错误处理机制: 路径验证:检查指定目录是否存在且可访问 权限检测:检测是否有足够的权限访问目录和文件 符号链接处理:正确处理符号链接,避免重复计算或无限循环 大文件处理:优化大文件的大小计算过程 内存保护:在处理大量文件时防止内存溢出 异常捕获:捕获并处理运行过程中可能出现的各种异常
  • import os import sys import argparse import json from datetime import datetime import matplotlib.pyplot as plt from collections import defaultdict class DiskSpaceAnalyzer: def __init__(self, path=”/”): self.path = path self.total_size = 0 self.file_count = 0 self.dir_count = 0 self.largest_files = [] self.dir_sizes = {} self.file_types = defaultdict(int) self.errors = [] def get_disk_usage(self): “””获取磁盘使用情况””” try: if os.name == ‘nt’: # Windows import shutil total, used, free = shutil.disk_usage(self.path) else: # Unix/Linux/macOS statvfs = os.statvfs(self.path) total = statvfs.f_frsize * statvfs.f_blocks free = statvfs.f_frsize * statvfs.f_bavail used = total – free return { ‘total’: total, ‘used’: used, ‘free’: free, ‘percentage’: (used / total) * 100 if total > 0 else 0 } except Exception as e: self.errors.append(f”获取磁盘使用情况失败: {e}”) return None def format_bytes(self, bytes_value): “””格式化字节单位””” for unit in [‘B’, ‘KB’, ‘MB’, ‘GB’, ‘TB’]: if bytes_value < 1024.0: return f”{bytes_value:.2f} {unit}” bytes_value /= 1024.0 return f”{bytes_value:.2f} PB” def get_file_extension(self, filename): “””获取文件扩展名””” _, ext = os.path.splitext(filename) return ext.lower() if ext else ‘no_extension’ def analyze_directory(self, max_depth=3, min_size_mb=1): “””分析目录大小””” print(f”开始分析目录: {self.path}”) print(f”最大深度: {max_depth}, 最小文件大小: {min_size_mb}MB”) try: self._walk_directory(self.path, 0, max_depth, min_size_mb * 1024 * 1024) self._sort_results() return True except Exception as e: self.errors.append(f”分析目录时出错: {e}”) return False def _walk_directory(self, current_path, current_depth, max_depth, min_size): “””递归遍历目录””” try: # 检查是否超过最大深度 if current_depth > max_depth: return # 获取目录内容 items = os.listdir(current_path) dir_size = 0 for item in items: item_path = os.path.join(current_path, item) try: # 跳过隐藏文件和目录 if item.startswith(‘.’): continue # 获取文件/目录信息 stat_info = os.stat(item_path) if os.path.isfile(item_path): # 处理文件 file_size = stat_info.st_size dir_size += file_size self.file_count += 1 # 记录大于最小大小的文件 if file_size >= min_size: self.largest_files.append({ ‘path’: item_path, ‘size’: file_size, ‘modified’: datetime.fromtimestamp(stat_info.st_mtime) }) # 统计文件类型 ext = self.get_file_extension(item) self.file_types[ext] += file_size elif os.path.isdir(item_path): # 处理目录 self.dir_count += 1 subdir_size = self._walk_directory(item_path, current_depth + 1, max_depth, min_size) dir_size += subdir_size except PermissionError: self.errors.append(f”权限不足: {item_path}”) except Exception as e: self.errors.append(f”处理 {item_path} 时出错: {e}”) # 记录当前目录大小 self.dir_sizes[current_path] = dir_size return dir_size except PermissionError: self.errors.append(f”权限不足,无法访问目录: {current_path}”) return 0 except Exception as e: self.errors.append(f”遍历目录 {current_path} 时出错: {e}”) return 0 def _sort_results(self): “””对结果进行排序””” # 按大小排序目录 self.dir_sizes = dict(sorted(self.dir_sizes.items(), key=lambda x: x[1], reverse=True)) # 按大小排序文件 self.largest_files.sort(key=lambda x: x[‘size’], reverse=True) # 按大小排序文件类型 self.file_types = dict(sorted(self.file_types.items(), key=lambda x: x[1], reverse=True)) def get_top_directories(self, count=10): “””获取最大的几个目录””” return dict(list(self.dir_sizes.items())[:count]) def get_top_files(self, count=10): “””获取最大的几个文件””” return self.largest_files[:count] def generate_text_report(self): “””生成文本报告””” report = [] report.append(“=” * 80) report.append(“磁盘空间使用分析报告”) report.append(“=” * 80) report.append(f”分析时间: {datetime.now().strftime(‘%Y-%m-%d %H:%M:%S’)}”) report.append(f”分析路径: {self.path}”) report.append(“”) # 磁盘使用情况 disk_usage = self.get_disk_usage() if disk_usage: report.append(“磁盘使用情况:”) report.append(f” 总空间: {self.format_bytes(disk_usage[‘total’])}”) report.append(f” 已使用: {self.format_bytes(disk_usage[‘used’])}”) report.append(f” 可用空间: {self.format_bytes(disk_usage[‘free’])}”) report.append(f” 使用率: {disk_usage[‘percentage’]:.2f}%”) report.append(“”) # 统计信息 report.append(“统计信息:”) report.append(f” 文件总数: {self.file_count:,}”) report.append(f” 目录总数: {self.dir_count:,}”) report.append(f” 总大小: {self.format_bytes(sum(self.dir_sizes.values()))}”) report.append(“”) # 最大的目录 report.append(“最大的目录 (Top 10):”) report.append(“-” * 50) top_dirs = self.get_top_directories(10) for i, (dir_path, size) in enumerate(top_dirs.items(), 1): # 只显示相对路径 relative_path = os.path.relpath(dir_path, self.path) if dir_path != self.path else “.” report.append(f”{i:2d}. {relative_path:<50} {self.format_bytes(size)}”) report.append(“”) # 最大的文件 report.append(“最大的文件 (Top 10):”) report.append(“-” * 50) top_files = self.get_top_files(10) for i, file_info in enumerate(top_files, 1): # 只显示相对路径 relative_path = os.path.relpath(file_info[‘path’], self.path) modified_time = file_info[‘modified’].strftime(‘%Y-%m-%d %H:%M:%S’) report.append(f”{i:2d}. {relative_path:<50} {self.format_bytes(file_info[‘size’])} ({modified_time})”) report.append(“”) # 文件类型统计 report.append(“文件类型统计 (Top 10):”) report.append(“-” * 50) top_types = dict(list(self.file_types.items())[:10]) for i, (ext, size) in enumerate(top_types.items(), 1): ext_display = ext if ext else ‘(无扩展名)’ report.append(f”{i:2d}. {ext_display:<20} {self.format_bytes(size)}”) report.append(“”) # 错误信息 if self.errors: report.append(“错误信息:”) report.append(“-” * 50) for error in self.errors[:10]: # 只显示前10个错误 report.append(f” {error}”) if len(self.errors) > 10: report.append(f” … 还有 {len(self.errors) – 10} 个错误”) report.append(“”) report.append(“=” * 80) return “n”.join(report) def generate_json_report(self, filename=None): “””生成JSON报告””” report = { ‘analysis_time’: datetime.now().isoformat(), ‘path’: self.path, ‘disk_usage’: self.get_disk_usage(), ‘statistics’: { ‘total_files’: self.file_count, ‘total_directories’: self.dir_count, ‘total_size’: sum(self.dir_sizes.values()) }, ‘top_directories’: self.get_top_directories(20), ‘top_files’: [ { ‘path’: f[‘path’], ‘size’: f[‘size’], ‘modified’: f[‘modified’].isoformat() } for f in self.get_top_files(20) ], ‘file_types’: self.file_types, ‘errors’: self.errors } if filename: try: with open(filename, ‘w’, encoding=’utf-8′) as f: json.dump(report, f, indent=2, ensure_ascii=False) print(f”JSON报告已保存到: {filename}”) return True except Exception as e: print(f”保存JSON报告时出错: {e}”) return False else: return json.dumps(report, indent=2, ensure_ascii=False) def generate_charts(self, prefix=”disk_analysis”): “””生成图表””” try: # 创建图表目录 chart_dir = f”{prefix}_charts” if not os.path.exists(chart_dir): os.makedirs(chart_dir) # 1. 目录大小饼图 top_dirs = self.get_top_directories(8) other_size = sum(self.dir_sizes.values()) – sum(top_dirs.values()) if top_dirs: labels = [os.path.basename(path) if path != self.path else ‘根目录’ for path in top_dirs.keys()] sizes = list(top_dirs.values()) if other_size > 0: labels.append(‘其他’) sizes.append(other_size) plt.figure(figsize=(10, 8)) plt.pie(sizes, labels=labels, autopct=’%1.1f%%’, startangle=90) plt.title(‘目录大小分布’) plt.axis(‘equal’) plt.savefig(os.path.join(chart_dir, f'{prefix}_directories.png’), dpi=300, bbox_inches=’tight’) plt.close() # 2. 文件类型柱状图 top_types = dict(list(self.file_types.items())[:10]) if top_types: labels = [ext if ext else ‘(无扩展名)’ for ext in top_types.keys()] sizes = [size / (1024*1024) for size in top_types.values()] # 转换为MB plt.figure(figsize=(12, 6)) plt.bar(labels, sizes) plt.title(‘文件类型大小分布 (MB)’) plt.xlabel(‘文件类型’) plt.ylabel(‘大小 (MB)’) plt.xticks(rotation=45) plt.tight_layout() plt.savefig(os.path.join(chart_dir, f'{prefix}_filetypes.png’), dpi=300, bbox_inches=’tight’) plt.close() # 3. 最大文件柱状图 top_files = self.get_top_files(10) if top_files: labels = [os.path.basename(f[‘path’]) for f in top_files] sizes = [f[‘size’] / (1024*1024) for f in top_files] # 转换为MB plt.figure(figsize=(12, 6)) plt.bar(labels, sizes) plt.title(‘最大文件大小 (MB)’) plt.xlabel(‘文件名’) plt.ylabel(‘大小 (MB)’) plt.xticks(rotation=45) plt.tight_layout() plt.savefig(os.path.join(chart_dir, f'{prefix}_largest_files.png’), dpi=300, bbox_inches=’tight’) plt.close() print(f”图表已保存到目录: {chart_dir}”) return True except Exception as e: print(f”生成图表时出错: {e}”) return False def main(): parser = argparse.ArgumentParser(description=”磁盘空间使用报告工具”) parser.add_argument(“path”, nargs=’?’, default=”.”, help=”要分析的目录路径 (默认: 当前目录)”) parser.add_argument(“-d”, “–depth”, type=int, default=3, help=”分析深度 (默认: 3)”) parser.add_argument(“-s”, “–min-size”, type=float, default=1.0, help=”最小文件大小(MB) (默认: 1.0)”) parser.add_argument(“-o”, “–output”, help=”保存文本报告到文件”) parser.add_argument(“-j”, “–json”, help=”保存JSON报告到文件”) parser.add_argument(“-c”, “–charts”, action=”store_true”, help=”生成图表”) parser.add_argument(“–chart-prefix”, default=”disk_analysis”, help=”图表文件前缀”) args = parser.parse_args() # 检查路径是否存在 if not os.path.exists(args.path): print(f”错误: 路径 ‘{args.path}’ 不存在”) sys.exit(1) if not os.path.isdir(args.path): print(f”错误: ‘{args.path}’ 不是一个目录”) sys.exit(1) try: analyzer = DiskSpaceAnalyzer(args.path) # 分析目录 if not analyzer.analyze_directory(args.depth, args.min_size): print(“目录分析失败”) sys.exit(1) # 生成文本报告 report = analyzer.generate_text_report() # 输出报告 if args.output: try: with open(args.output, ‘w’, encoding=’utf-8′) as f: f.write(report) print(f”文本报告已保存到: {args.output}”) except Exception as e: print(f”保存文本报告时出错: {e}”) else: print(report) # 生成JSON报告 if args.json: analyzer.generate_json_report(args.json) # 生成图表 if args.charts: analyzer.generate_charts(args.chart_prefix) except KeyboardInterrupt: print(“nn用户中断操作”) except Exception as e: print(f”程序执行出错: {e}”) sys.exit(1) if __name__ == “__main__”: main()
  • 这个磁盘空间使用报告工具提供了一个全面的磁盘空间分析解决方案,能够深入分析目录结构并生成详细的使用报告。它不仅可以显示磁盘的整体使用情况,还能识别占用空间最大的目录和文件,帮助用户优化存储空间。工具支持多种输出格式,包括易于阅读的文本报告、便于程序处理的JSON数据以及直观的图表,满足不同用户的需求。无论是系统管理员进行日常维护,还是普通用户清理存储空间,这个工具都能提供有价值的帮助。 到此这篇关于Python检查与分析磁盘空间使用情况并生成报告的文章就介绍到这了,更多相关Python磁盘空间内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客! 您可能感兴趣的文章: 利用python检查磁盘空间使用情况的代码实现 用python监控服务器的cpu,磁盘空间,内存,超过邮件报警 python3实现磁盘空间监控 python3监控CentOS磁盘空间脚本 Linux 发邮件磁盘空间监控(python)
  • 目录
    • 简介
    • 功能介绍
    • 应用场景
    • 报错处理
    • 代码实现
    • 使用方法
      • 基本使用
      • 命令行参数说明
      • 使用示例
    • 总结

      磁盘空间管理是系统维护中的重要环节。随着数据的不断增长,磁盘空间可能会逐渐被占满,导致系统性能下降甚至崩溃。定期检查和分析磁盘空间使用情况,可以帮助我们及时发现空间不足的问题,并采取相应的措施。本文将介绍一个实用的Python脚本——磁盘空间使用报告工具,它可以生成详细的磁盘空间使用报告,帮助用户了解磁盘空间的分布情况。

      这个磁盘空间使用报告工具具有以下核心功能:

      • 磁盘信息获取:获取系统中所有磁盘分区的总空间、已用空间和可用空间
      • 目录大小分析:深入分析指定目录下各子目录和文件的大小分布
      • 可视化报告:生成直观的饼图和柱状图展示磁盘空间使用情况
      • 详细统计信息:提供文件数量、目录数量、最大文件等统计信息
      • 多格式输出:支持文本报告、JSON数据和图表等多种输出格式
      • 过滤功能:可以根据文件类型、大小等条件过滤分析结果
      • 定时任务支持:可以集成到定时任务中定期生成报告
      • 跨平台兼容:支持Windows、Linux和macOS操作系统

      这个工具适用于以下场景:

      • 系统维护:定期检查服务器磁盘空间使用情况
      • 存储优化:识别占用空间较大的目录和文件
      • 容量规划:根据历史数据预测存储需求
      • 故障排查:定位磁盘空间不足的原因
      • 资源审计:审计系统中的大文件和无用文件
      • 备份管理:分析备份目录的空间使用情况

      脚本包含了完善的错误处理机制:

      • 路径验证:检查指定目录是否存在且可访问
      • 权限检测:检测是否有足够的权限访问目录和文件
      • 符号链接处理:正确处理符号链接,避免重复计算或无限循环
      • 大文件处理:优化大文件的大小计算过程
      • 内存保护:在处理大量文件时防止内存溢出
      • 异常捕获:捕获并处理运行过程中可能出现的各种异常

      import os
      import sys
      import argparse
      import json
      from datetime import datetime
      import matplotlib.pyplot as plt
      from collections import defaultdict
      
      class DiskSpaceAnalyzer:
          def __init__(self, path="/"):
              self.path = path
              self.total_size = 0
              self.file_count = 0
              self.dir_count = 0
              self.largest_files = []
              self.dir_sizes = {}
              self.file_types = defaultdict(int)
              self.errors = []
              
          def get_disk_usage(self):
              """获取磁盘使用情况"""
              try:
                  if os.name == 'nt':  # Windows
                      import shutil
                      total, used, free = shutil.disk_usage(self.path)
                  else:  # Unix/Linux/macOS
                      statvfs = os.statvfs(self.path)
                      total = statvfs.f_frsize * statvfs.f_blocks
                      free = statvfs.f_frsize * statvfs.f_bavail
                      used = total - free
                      
                  return {
                      'total': total,
                      'used': used,
                      'free': free,
                      'percentage': (used / total) * 100 if total > 0 else 0
                  }
              except Exception as e:
                  self.errors.append(f"获取磁盘使用情况失败: {e}")
                  return None
                  
          def format_bytes(self, bytes_value):
              """格式化字节单位"""
              for unit in ['B', 'KB', 'MB', 'GB', 'TB']:
                  if bytes_value < 1024.0:
                      return f"{bytes_value:.2f} {unit}"
                  bytes_value /= 1024.0
              return f"{bytes_value:.2f} PB"
              
          def get_file_extension(self, filename):
              """获取文件扩展名"""
              _, ext = os.path.splitext(filename)
              return ext.lower() if ext else 'no_extension'
              
          def analyze_directory(self, max_depth=3, min_size_mb=1):
              """分析目录大小"""
              print(f"开始分析目录: {self.path}")
              print(f"最大深度: {max_depth}, 最小文件大小: {min_size_mb}MB")
              
              try:
                  self._walk_directory(self.path, 0, max_depth, min_size_mb * 1024 * 1024)
                  self._sort_results()
                  return True
              except Exception as e:
                  self.errors.append(f"分析目录时出错: {e}")
                  return False
                  
          def _walk_directory(self, current_path, current_depth, max_depth, min_size):
              """递归遍历目录"""
              try:
                  # 检查是否超过最大深度
                  if current_depth > max_depth:
                      return
                      
                  # 获取目录内容
                  items = os.listdir(current_path)
                  dir_size = 0
                  
                  for item in items:
                      item_path = os.path.join(current_path, item)
                      
                      try:
                          # 跳过隐藏文件和目录
                          if item.startswith('.'):
                              continue
                              
                          # 获取文件/目录信息
                          stat_info = os.stat(item_path)
                          
                          if os.path.isfile(item_path):
                              # 处理文件
                              file_size = stat_info.st_size
                              dir_size += file_size
                              self.file_count += 1
                              
                              # 记录大于最小大小的文件
                              if file_size >= min_size:
                                  self.largest_files.append({
                                      'path': item_path,
                                      'size': file_size,
                                      'modified': datetime.fromtimestamp(stat_info.st_mtime)
                                  })
                                  
                              # 统计文件类型
                              ext = self.get_file_extension(item)
                              self.file_types[ext] += file_size
                              
                          elif os.path.isdir(item_path):
                              # 处理目录
                              self.dir_count += 1
                              subdir_size = self._walk_directory(item_path, current_depth + 1, max_depth, min_size)
                              dir_size += subdir_size
                              
                      except PermissionError:
                          self.errors.append(f"权限不足: {item_path}")
                      except Exception as e:
                          self.errors.append(f"处理 {item_path} 时出错: {e}")
                          
                  # 记录当前目录大小
                  self.dir_sizes[current_path] = dir_size
                  return dir_size
                  
              except PermissionError:
                  self.errors.append(f"权限不足,无法访问目录: {current_path}")
                  return 0
              except Exception as e:
                  self.errors.append(f"遍历目录 {current_path} 时出错: {e}")
                  return 0
                  
          def _sort_results(self):
              """对结果进行排序"""
              # 按大小排序目录
              self.dir_sizes = dict(sorted(self.dir_sizes.items(), key=lambda x: x[1], reverse=True))
              
              # 按大小排序文件
              self.largest_files.sort(key=lambda x: x['size'], reverse=True)
              
              # 按大小排序文件类型
              self.file_types = dict(sorted(self.file_types.items(), key=lambda x: x[1], reverse=True))
              
          def get_top_directories(self, count=10):
              """获取最大的几个目录"""
              return dict(list(self.dir_sizes.items())[:count])
              
          def get_top_files(self, count=10):
              """获取最大的几个文件"""
              return self.largest_files[:count]
              
          def generate_text_report(self):
              """生成文本报告"""
              report = []
              report.append("=" * 80)
              report.append("磁盘空间使用分析报告")
              report.append("=" * 80)
              report.append(f"分析时间: {datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
              report.append(f"分析路径: {self.path}")
              report.append("")
              
              # 磁盘使用情况
              disk_usage = self.get_disk_usage()
              if disk_usage:
                  report.append("磁盘使用情况:")
                  report.append(f"  总空间: {self.format_bytes(disk_usage['total'])}")
                  report.append(f"  已使用: {self.format_bytes(disk_usage['used'])}")
                  report.append(f"  可用空间: {self.format_bytes(disk_usage['free'])}")
                  report.append(f"  使用率: {disk_usage['percentage']:.2f}%")
                  report.append("")
                  
              # 统计信息
              report.append("统计信息:")
              report.append(f"  文件总数: {self.file_count:,}")
              report.append(f"  目录总数: {self.dir_count:,}")
              report.append(f"  总大小: {self.format_bytes(sum(self.dir_sizes.values()))}")
              report.append("")
              
              # 最大的目录
              report.append("最大的目录 (Top 10):")
              report.append("-" * 50)
              top_dirs = self.get_top_directories(10)
              for i, (dir_path, size) in enumerate(top_dirs.items(), 1):
                  # 只显示相对路径
                  relative_path = os.path.relpath(dir_path, self.path) if dir_path != self.path else "."
                  report.append(f"{i:2d}. {relative_path:<50} {self.format_bytes(size)}")
              report.append("")
              
              # 最大的文件
              report.append("最大的文件 (Top 10):")
              report.append("-" * 50)
              top_files = self.get_top_files(10)
              for i, file_info in enumerate(top_files, 1):
                  # 只显示相对路径
                  relative_path = os.path.relpath(file_info['path'], self.path)
                  modified_time = file_info['modified'].strftime('%Y-%m-%d %H:%M:%S')
                  report.append(f"{i:2d}. {relative_path:<50} {self.format_bytes(file_info['size'])} ({modified_time})")
              report.append("")
              
              # 文件类型统计
              report.append("文件类型统计 (Top 10):")
              report.append("-" * 50)
              top_types = dict(list(self.file_types.items())[:10])
              for i, (ext, size) in enumerate(top_types.items(), 1):
                  ext_display = ext if ext else '(无扩展名)'
                  report.append(f"{i:2d}. {ext_display:<20} {self.format_bytes(size)}")
              report.append("")
              
              # 错误信息
              if self.errors:
                  report.append("错误信息:")
                  report.append("-" * 50)
                  for error in self.errors[:10]:  # 只显示前10个错误
                      report.append(f"  {error}")
                  if len(self.errors) > 10:
                      report.append(f"  ... 还有 {len(self.errors) - 10} 个错误")
                  report.append("")
                  
              report.append("=" * 80)
              return "n".join(report)
              
          def generate_json_report(self, filename=None):
              """生成JSON报告"""
              report = {
                  'analysis_time': datetime.now().isoformat(),
                  'path': self.path,
                  'disk_usage': self.get_disk_usage(),
                  'statistics': {
                      'total_files': self.file_count,
                      'total_directories': self.dir_count,
                      'total_size': sum(self.dir_sizes.values())
                  },
                  'top_directories': self.get_top_directories(20),
                  'top_files': [
                      {
                          'path': f['path'],
                          'size': f['size'],
                          'modified': f['modified'].isoformat()
                      }
                      for f in self.get_top_files(20)
                  ],
                  'file_types': self.file_types,
                  'errors': self.errors
              }
              
              if filename:
                  try:
                      with open(filename, 'w', encoding='utf-8') as f:
                          json.dump(report, f, indent=2, ensure_ascii=False)
                      print(f"JSON报告已保存到: {filename}")
                      return True
                  except Exception as e:
                      print(f"保存JSON报告时出错: {e}")
                      return False
              else:
                  return json.dumps(report, indent=2, ensure_ascii=False)
                  
          def generate_charts(self, prefix="disk_analysis"):
              """生成图表"""
              try:
                  # 创建图表目录
                  chart_dir = f"{prefix}_charts"
                  if not os.path.exists(chart_dir):
                      os.makedirs(chart_dir)
                      
                  # 1. 目录大小饼图
                  top_dirs = self.get_top_directories(8)
                  other_size = sum(self.dir_sizes.values()) - sum(top_dirs.values())
                  
                  if top_dirs:
                      labels = [os.path.basename(path) if path != self.path else '根目录' for path in top_dirs.keys()]
                      sizes = list(top_dirs.values())
                      
                      if other_size > 0:
                          labels.append('其他')
                          sizes.append(other_size)
                          
                      plt.figure(figsize=(10, 8))
                      plt.pie(sizes, labels=labels, autopct='%1.1f%%', startangle=90)
                      plt.title('目录大小分布')
                      plt.axis('equal')
                      plt.savefig(os.path.join(chart_dir, f'{prefix}_directories.png'), 
                                 dpi=300, bbox_inches='tight')
                      plt.close()
                      
                  # 2. 文件类型柱状图
                  top_types = dict(list(self.file_types.items())[:10])
                  if top_types:
                      labels = [ext if ext else '(无扩展名)' for ext in top_types.keys()]
                      sizes = [size / (1024*1024) for size in top_types.values()]  # 转换为MB
                      
                      plt.figure(figsize=(12, 6))
                      plt.bar(labels, sizes)
                      plt.title('文件类型大小分布 (MB)')
                      plt.xlabel('文件类型')
                      plt.ylabel('大小 (MB)')
                      plt.xticks(rotation=45)
                      plt.tight_layout()
                      plt.savefig(os.path.join(chart_dir, f'{prefix}_filetypes.png'), 
                                 dpi=300, bbox_inches='tight')
                      plt.close()
                      
                  # 3. 最大文件柱状图
                  top_files = self.get_top_files(10)
                  if top_files:
                      labels = [os.path.basename(f['path']) for f in top_files]
                      sizes = [f['size'] / (1024*1024) for f in top_files]  # 转换为MB
                      
                      plt.figure(figsize=(12, 6))
                      plt.bar(labels, sizes)
                      plt.title('最大文件大小 (MB)')
                      plt.xlabel('文件名')
                      plt.ylabel('大小 (MB)')
                      plt.xticks(rotation=45)
                      plt.tight_layout()
                      plt.savefig(os.path.join(chart_dir, f'{prefix}_largest_files.png'), 
                                 dpi=300, bbox_inches='tight')
                      plt.close()
                      
                  print(f"图表已保存到目录: {chart_dir}")
                  return True
                  
              except Exception as e:
                  print(f"生成图表时出错: {e}")
                  return False
      
      def main():
          parser = argparse.ArgumentParser(description="磁盘空间使用报告工具")
          parser.add_argument("path", nargs='?', default=".", help="要分析的目录路径 (默认: 当前目录)")
          parser.add_argument("-d", "--depth", type=int, default=3, help="分析深度 (默认: 3)")
          parser.add_argument("-s", "--min-size", type=float, default=1.0, 
                             help="最小文件大小(MB) (默认: 1.0)")
          parser.add_argument("-o", "--output", help="保存文本报告到文件")
          parser.add_argument("-j", "--json", help="保存JSON报告到文件")
          parser.add_argument("-c", "--charts", action="store_true", help="生成图表")
          parser.add_argument("--chart-prefix", default="disk_analysis", help="图表文件前缀")
          
          args = parser.parse_args()
          
          # 检查路径是否存在
          if not os.path.exists(args.path):
              print(f"错误: 路径 '{args.path}' 不存在")
              sys.exit(1)
              
          if not os.path.isdir(args.path):
              print(f"错误: '{args.path}' 不是一个目录")
              sys.exit(1)
              
          try:
              analyzer = DiskSpaceAnalyzer(args.path)
              
              # 分析目录
              if not analyzer.analyze_directory(args.depth, args.min_size):
                  print("目录分析失败")
                  sys.exit(1)
                  
              # 生成文本报告
              report = analyzer.generate_text_report()
              
              # 输出报告
              if args.output:
                  try:
                      with open(args.output, 'w', encoding='utf-8') as f:
                          f.write(report)
                      print(f"文本报告已保存到: {args.output}")
                  except Exception as e:
                      print(f"保存文本报告时出错: {e}")
              else:
                  print(report)
                  
              # 生成JSON报告
              if args.json:
                  analyzer.generate_json_report(args.json)
                  
              # 生成图表
              if args.charts:
                  analyzer.generate_charts(args.chart_prefix)
                  
          except KeyboardInterrupt:
              print("nn用户中断操作")
          except Exception as e:
              print(f"程序执行出错: {e}")
              sys.exit(1)
      
      if __name__ == "__main__":
          main()
      

      # 分析当前目录
      python disk_space_report.py
      
      # 分析指定目录
      python disk_space_report.py /path/to/directory
      
      # 设置分析深度为5层
      python disk_space_report.py /path/to/directory -d 5
      
      # 只分析大于10MB的文件
      python disk_space_report.py /path/to/directory -s 10
      
      # 保存报告到文件
      python disk_space_report.py /path/to/directory -o report.txt
      
      # 生成JSON报告
      python disk_space_report.py /path/to/directory -j report.json
      
      # 生成图表
      python disk_space_report.py /path/to/directory -c --chart-prefix my_analysis
      

      • path: 要分析的目录路径,默认为当前目录
      • -d, --depth: 分析深度,默认为3层
      • -s, --min-size: 最小文件大小(MB),默认为1.0MB
      • -o, --output: 保存文本报告到指定文件
      • -j, --json: 保存JSON报告到指定文件
      • -c, --charts: 生成图表
      • --chart-prefix: 图表文件前缀,默认为"disk_analysis"

      基本分析

      python disk_space_report.py /home/user
      

      深度分析并保存报告

      python disk_space_report.py /var/log -d 5 -s 0.5 -o log_analysis.txt -j log_analysis.json -c
      

      分析系统根目录

      python disk_space_report.py / -d 2 -s 50 -o system_report.txt
      

      这个磁盘空间使用报告工具提供了一个全面的磁盘空间分析解决方案,能够深入分析目录结构并生成详细的使用报告。它不仅可以显示磁盘的整体使用情况,还能识别占用空间最大的目录和文件,帮助用户优化存储空间。工具支持多种输出格式,包括易于阅读的文本报告、便于程序处理的JSON数据以及直观的图表,满足不同用户的需求。无论是系统管理员进行日常维护,还是普通用户清理存储空间,这个工具都能提供有价值的帮助。

      到此这篇关于Python检查与分析磁盘空间使用情况并生成报告的文章就介绍到这了,更多相关Python磁盘空间内容请搜索风君子博客以前的文章或继续浏览下面的相关文章希望大家以后多多支持风君子博客!

      您可能感兴趣的文章:

      • 利用python检查磁盘空间使用情况的代码实现
      • 用python监控服务器的cpu,磁盘空间,内存,超过邮件报警
      • python3实现磁盘空间监控
      • python3监控CentOS磁盘空间脚本
      • Linux 发邮件磁盘空间监控(python)

      站内搜索