目标:遍历文件夹,计算文件夹下包含文件和文件夹的大小。将这些结果存入python自带的数据库。
用大模型帮我设计并实现。
创建目录结构如下所示:
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 shutil
def 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_ok
为True
,无论目标目录是否存在,os.makedirs
会执行,不会报错。exist_ok
为False
,并且目标目录已经存在,os.makedirs
会引发一个FileExistsError
异常。exist_ok=True
允许函数在调用时多次执行,即使已经创建了目录结构,也不会引发错误。
设计三个函数:
get_file_size(file_path)
函数:
file_path
。os.path.getsize
函数获取。format_size(size_bytes)
函数:
size_bytes
。get_directory_size(directory_path)
函数:
directory_path
。os.walk
遍历目录,得到每个文件的路径。get_file_size
函数获取其大小,并累计到总大小。get_directory_size
函数,将返回的子目录大小累加到总大小。这样,通过这三个函数的协作,可以获取文件和目录的大小信息,并且通过 format_size
函数,可以将字节数格式化为易读的字符串。
import os
def 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:
break
size_bytes /= 1024.0
return f"{size_bytes:.2f} {unit}"
def get_directory_size(directory_path):
"""
递归计算目录大小,包括目录中所有文件和子目录的大小
"""
total_size = 0
for 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_size
if __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
回顾上面的计算文件夹大小的程序,可能有些可以改进的方向
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_bytes
except (PermissionError, FileNotFoundError) as e:
print(f"访问文件出错: {e}")
return 0
except Exception as e:
print(f"出现异常: {e}")
return 0
对 get_directory_size 函数进行异常处理
def get_directory_size(directory_path):
"""
递归计算目录大小,包括目录中所有文件和子目录的大小
"""
total_size = 0
try:
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 0
return total_size