【笔记】计算文件夹的大小

目标:遍历文件夹,计算文件夹下包含文件和文件夹的大小。将这些结果存入python自带的数据库。

用大模型帮我设计并实现。

Step1 创建一个测试用的目录结构

创建目录结构如下所示:

TestDirectory/
│
├── EmptyFolder/
│
├── SmallFiles/
│   ├── file1.txt (1 KB)
│   ├── file2.txt (2 KB)
│   └── file3.txt (3 KB)
│
├── LargeFiles/
│   ├── big_file1.bin (10 MB)
│   ├── big_file2.bin (20 MB)
│   └── big_file3.bin (30 MB)
│
└── NestedFolders/├── Subfolder1/│   ├── file4.txt (4 KB)│   ├── file5.txt (5 KB)│   └── EmptySubfolder1/│├── Subfolder2/│   ├── file6.txt (6 KB)│   └── EmptySubfolder2/│└── Subfolder3/├── file7.txt (7 KB)└── EmptySubfolder3/
import os
import shutildef create_test_directory(root_path):# 创建根目录os.makedirs(root_path, exist_ok=True)# 创建空目录empty_folder_path = os.path.join(root_path, 'EmptyFolder')os.makedirs(empty_folder_path, exist_ok=True)# 创建包含小文件的目录small_files_path = os.path.join(root_path, 'SmallFiles')os.makedirs(small_files_path, exist_ok=True)for i in range(1, 4):file_path = os.path.join(small_files_path, f'file{i}.txt')with open(file_path, 'w') as file:file.write('x' * (i * 1024))  # 生成大小为 i KB 的文件# 创建包含大文件的目录large_files_path = os.path.join(root_path, 'LargeFiles')os.makedirs(large_files_path, exist_ok=True)for i in range(1, 4):file_path = os.path.join(large_files_path, f'big_file{i}.bin')with open(file_path, 'wb') as file:file.write(os.urandom(i * 10 * 1024 * 1024))  # 生成大小为 i * 10 MB 的二进制文件# 创建多层次嵌套目录nested_folders_path = os.path.join(root_path, 'NestedFolders')os.makedirs(nested_folders_path, exist_ok=True)for i in range(1, 4):subfolder_path = os.path.join(nested_folders_path, f'Subfolder{i}')os.makedirs(subfolder_path, exist_ok=True)file_path = os.path.join(subfolder_path, f'file{i + 3}.txt')with open(file_path, 'w') as file:file.write('x' * ((i + 3) * 1024))empty_subfolder_path = os.path.join(subfolder_path, f'EmptySubfolder{i}')os.makedirs(empty_subfolder_path, exist_ok=True)

os.makedirs函数中,exist_ok参数用于指定是否在目录已经存在的情况下忽略错误。

  • 如果exist_okTrue,无论目标目录是否存在,os.makedirs会执行,不会报错。
  • 如果exist_okFalse,并且目标目录已经存在,os.makedirs会引发一个FileExistsError异常。

exist_ok=True 允许函数在调用时多次执行,即使已经创建了目录结构,也不会引发错误。

Step2 遍历文件夹,计算文件夹大小

设计三个函数:

  1. get_file_size(file_path) 函数:

    • 输入:文件路径 file_path
    • 输出:返回该文件的大小(字节数),使用 os.path.getsize 函数获取。
  2. format_size(size_bytes) 函数:

    • 输入:一个表示字节数的整数 size_bytes
    • 输出:返回格式化后的字符串,该字符串包含适当的单位(B、KB、MB、GB)以及转换后的大小值。该函数通过迭代循环,将字节数转换为合适的单位。
  3. get_directory_size(directory_path) 函数:

    • 输入:目录路径 directory_path
    • 输出:返回该目录及其子目录中所有文件的总大小。
    • 思路:
      • 使用 os.walk 遍历目录,得到每个文件的路径。
      • 对于每个文件,调用 get_file_size 函数获取其大小,并累计到总大小。
      • 对于每个子目录,递归调用 get_directory_size 函数,将返回的子目录大小累加到总大小。
      • 返回总大小。

这样,通过这三个函数的协作,可以获取文件和目录的大小信息,并且通过 format_size 函数,可以将字节数格式化为易读的字符串。

import osdef get_file_size(file_path):"""计算文件大小(字节数)"""return os.path.getsize(file_path)def format_size(size_bytes):"""将字节数格式化为人类可读的字符串"""for unit in ['B', 'KB', 'MB', 'GB', 'TB']:if size_bytes < 1024.0:breaksize_bytes /= 1024.0return f"{size_bytes:.2f} {unit}"def get_directory_size(directory_path):"""递归计算目录大小,包括目录中所有文件和子目录的大小"""total_size = 0for dirpath, dirnames, filenames in os.walk(directory_path):# 计算文件大小for filename in filenames:file_path = os.path.join(dirpath, filename)total_size += get_file_size(file_path)# 计算子目录大小for dirname in dirnames:subdirectory_path = os.path.join(dirpath, dirname)total_size += get_directory_size(subdirectory_path)return total_size

上面返回的total_size是字节数。

另外说一下,函数中用到的 print(f"xxxx") 中的 f"xxxx" 是一个 f-string,是一种字符串格式化的方式,是在字符串前加上 f 或 F 前缀的字符串字面值。它允许在字符串中嵌入表达式,这些表达式会在运行时求值,并将结果插入到字符串中。可以使用大括号 {} 括起表达式,这些表达式将在运行时被替换为相应的值。例如:

name = "秦汉唐"
age = 25
print(f"姓名: {name} \t年龄 {age}")

f-string 中的 {name} 和 {age} 会分别被替换为变量 name 和 age 的值。

在测试的时候(testRun.py中):

import os
import shutil
from folder_size_calculator import get_directory_size, format_size, get_file_sizeif __name__=="__main__":# 测试函数create_test_directory('TestDirectory')# 测试directory_path = "TestDirectory"  # 替换为你的目录路径total_size = get_directory_size(directory_path)formatted_size = format_size(total_size)print(f" '{directory_path}' 文件夹大小为: {formatted_size}")

执行testRun.py,结果类似:

>python testRun.py'TestDirectory' 文件夹大小为: 120.07 MB

Step3 优化

回顾上面的计算文件夹大小的程序,可能有些可以改进的方向

  • 异常问题: 目前的代码缺少对一些异常情况的处理,例如无法访问的文件或目录。
  • 性能问题: 对于非常大的目录结构,递归遍历可能会导致重复计算,可能影响计算文件大小效率。
  • 符号链接问题: 目前的程序不处理符号链接,可能会导致计算错误或无限循环。
  • 文件类型判断和过滤问题: 目前程序对文件和目录的处理方式一样,没有区分文件类型。
  1. 异常处理问题
    因为是对文件进行处理,所以通过增加文件处理异常:
try:# 尝试获取文件大小或目录列表# ...
except (PermissionError, OSError) as e:print(f"Error accessing file or directory: {e}")
except FileNotFoundError as e:print(f"File not found: {e}")
except Exception as e:print(f"An unexpected error occurred: {e}")

对 get_file_size 函数进行异常处理

def get_file_size(file_path):"""计算文件大小(字节数)"""try:size_bytes = os.path.getsize(file_path)return size_bytesexcept (PermissionError, FileNotFoundError) as e:print(f"访问文件出错: {e}")return 0except Exception as e:print(f"出现异常: {e}")return 0

对 get_directory_size 函数进行异常处理

def get_directory_size(directory_path):"""递归计算目录大小,包括目录中所有文件和子目录的大小"""total_size = 0try:for dirpath, dirnames, filenames in os.walk(directory_path):# 计算文件大小for filename in filenames:file_path = os.path.join(dirpath, filename)total_size += os.path.getsize(file_path)# 计算子目录大小for dirname in dirnames:subdirectory_path = os.path.join(dirpath, dirname)total_size += get_directory_size(subdirectory_path)except (PermissionError, FileNotFoundError) as e:print(f"访问文件异常: {e}")return 0  # 或者抛出其他异常except Exception as e:print(f"出现异常: {e}")return 0return total_size
  1. 性能问题
    我想利用数据库存储已经处理过的文件和文件夹。最简单的方式,数据库就用python自带的数据库,边做便设置数据库格式。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/660236.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

结合创新!11种多尺度特征融合方法,附论文和代码

随着深度学习和计算机视觉技术的快速发展&#xff0c;多尺度特征融合已经成为一个备受关注的、不断探索的研究方向&#xff0c;它通过捕捉不同尺度和层次上的特征信息&#xff0c;提高对图像和视频内容的理解能力&#xff0c;为图像处理、计算机视觉和深度学习等领域的应用提供…

鸿蒙(HarmonyOS)项目方舟框架(ArkUI)之DatePicker组件

鸿蒙&#xff08;HarmonyOS&#xff09;项目方舟框架&#xff08;ArkUI&#xff09;之DatePicker组件 一、操作环境 操作系统: Windows 10 专业版、IDE:DevEco Studio 3.1、SDK:HarmonyOS 3.1 二、DatePicker组件 日期选择器组件&#xff0c;用于根据指定日期范围创建日期滑…

Delphi TStringList常用的方法和属性

Delphi TStringList 是一个常用的字符串列表类&#xff0c;用于存储和操作字符串列表。以下是一些常用的方法和属性&#xff1a; 方法&#xff1a; Add&#xff1a;向列表末尾添加一个字符串。Insert&#xff1a;在指定位置插入一个字符串。Delete&#xff1a;删除指定位置的…

字符串操作函数1

1.strcpy使用 使用这个函数我们可以进行字符串拷贝。它有两个参数&#xff0c;第一个参数是指向目标空间&#xff0c;第二个参数是指向需要拷贝的字符串。返回值为拷贝完成后指向的字符串首地址。头文件为<string.h> 演示如下&#xff1a; 注意&#xff1a; • 源字符…

TensorFlow2实战-系列教程4:数据增强

&#x1f9e1;&#x1f49b;&#x1f49a;TensorFlow2实战-系列教程 总目录 有任何问题欢迎在下面留言 本篇文章的代码运行界面均在Jupyter Notebook中进行 本篇文章配套的代码资源已经上传 猫狗识别1 数据增强 猫狗识别2------数据增强 猫狗识别3------迁移学习 对于图像数据…

RS485自动收发电路震荡的问题

电路 设计初衷 电源5V 选择5V的原因&#xff0c;差分2.5V比1.5V可以提高传输能力 TTL输入 3.3V电平满足需求 TTL输出 4.5V了&#xff0c;MCU是3.3V平台 这样就分为两种情况 MCU接收端可以容忍5V输入 MCU接收端不可以容忍5V输入&#xff0c;就要进行电压转换&#xff0c;我这里使…

MacOS X 中 OpenGL 环境搭建 Makefile的方式

1&#xff0c;预备环境 安装 brew&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" 安装glfw&#xff1a; brew install glfw 安装glew&#xff1a; brew install glew 2.编译 下载源代码…

Linux内核--设备驱动(一)驱动的结构介绍

目录 一、引言 二、I/O架构 三、字符设备基本构成 ------>3.1、cdev ------>3.2、char_device_struct ------>3.3、cdev_map 四、打开字符设备 ------>4.1、加载 ------>4.2、创建文件设备 ------>4.3、打开字符设备 ------>4.4、写入字符设备…

本地搭建Plex私人影音网站并结合内网穿透实现公网远程访问

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…

【数据库】mysql触发器使用

题目&#xff1a; 创建职工表以及职工工资表职工表字段&#xff1a;工号&#xff0c;姓名&#xff0c;性别&#xff0c;年龄工资表字段&#xff1a;编号自增&#xff0c;职工工号&#xff0c;基础工资10000通过触发器实现&#xff1a;对职工进行添加时 工资表中也要体现当前职…

Google Play 内购实现

接上一次苹果内购记录-CSDN博客&#xff0c;我又接了一把 Google Play 内购。 Google Play 内购实现 - 掘金 (juejin.cn) 吐槽一下CSDN的编辑器&#xff0c;对多图Markdown来说体验可太差了&#xff0c;去掘金看吧 &#xff08;其实就是懒&#xff0c;不想手动上传所有图&am…

docker下,容器无法启动,要删除里面的文件

第一步&#xff1a;进入docker cd /var/lib/docker 第二步&#xff1a;查找&#xff0c;我这里是拼音分词器 find ./ -name py 第三步&#xff1a;得到路径 第四步&#xff1a;删除或复制或移动&#xff0c;我这里是删除py文件夹 rm -rf ./over那一串 第五步&#xff1a;想干…

D2025——双通道音频功率放大电路,外接元件少, 通道分离性好,3V 的低压下可正常使用

D2025 为立体声音频功率放大集成电路&#xff0c;适用于各类袖珍或便携式立体声 收录机中作功率放放大器。 D2025 采用 DIP16 封装形式。 主要特点&#xff1a;  适用于立体声或 BTL 工作模式  外接元件少  通道分离性好  电源电压范围宽&#xff08;3V~12V…

【JavaEE spring】SpringBoot 统一功能处理

SpringBoot 统一功能处理 1. 拦截器1.1 拦截器快速⼊⻔1.2 拦截器详解1.2.1 拦截路径1.2.2 拦截器执⾏流程 1.3 登录校验1.3.1 定义拦截器1.3.2 注册配置拦截器 2. 统⼀数据返回格式2.1 快速⼊⻔2.2 存在问题2.3 案例代码修改2.4 优点 3. 统⼀异常处理 1. 拦截器 后端程序根据…

Chakra UI:构建 Web 设计的未来

Chakra UI&#xff1a;构建 Web 设计的未来 在当今的Web开发领域&#xff0c;构建现代、可访问的用户界面是一个重要的任务。为了满足这一需求&#xff0c;开发者需要一个强大而易用的UI组件库。而Chakra UI作为一个基于React的开源组件库&#xff0c;正是为了解决这个问题而诞…

vue3 [Vue warn]: Unhandled error during execution of scheduler flush

文章目录 前言一、报错截图二、排除问题思路相关问题 Vue3 优雅解决方法异步组件异同之处&#xff1a;好处&#xff1a;在使用异步组件时&#xff0c;有几个注意点&#xff1a; vue3 定义与使用异步组件 总结 前言 Bug 记录。开发环境运行正常&#xff0c;构建后时不时触发下面…

hal库stm32串口接收不定长数据

参考博客&#xff1a; https://blog.csdn.net/qq_41830158/article/details/121254705 按下面步骤修改实测可用 步骤&#xff1a; 添加串口接收所需变量   打开uart.c文件&#xff0c;在文件顶部的USER CODE BEGIN 0下方添加下列变量 volatile uint8_t rx1_len 0; //接收…

C语言第十五弹---操作符(上)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】 操作符 1、操作符的分类 2、二进制和进制转换 2.1、2进制转10进制 2.1.1、10进制转2进制数字 2.2、2进制转8进制和16进制 2.2.2、2进制转16进制 3. 原码、反…

C++完成使用map Update数据 二进制数据

1、在LXMysql.h和LXMysql.cpp分别定义和编写关于pin语句的代码 //获取更新数据的sql语句 where语句中用户要包含where 更新std::string GetUpdatesql(XDATA kv, std::string table, std::string where); std::string LXMysql::GetUpdatesql(XDATA kv, std::string table, std…

智能小车案例:基于Raspberry Pi的自动巡航与避障系统

项目背景 随着物联网技术的不断发展&#xff0c;智能小车成为了现代生活和工业自动化中的重要工具。为了实现智能小车的自动巡航与避障功能&#xff0c;我们采用了Raspberry Pi作为主控制器&#xff0c;结合传感器和执行器&#xff0c;构建了一个完整的系统。 所需材料 Raspber…