目录
〇、问题描述
在写一个统计文件夹大小的函数时,使用os.path.getsize()出现找不到文件的情况。
def count_folder_size(file_path):
# 计算文件夹的大小
total_size_byte = 0
for root, dirs, files in os.walk(file_path):
for file in files:
file_path = os.path.join(root, file).replace("\\", "/")
total_size_byte += os.path.getsize(file_path) # 报错:FileNotFoundError: [WinError 3] 系统找不到指定的路径
return total_size_byte
经确认发现文件实际上是存在的,尝试将文件名改短,程序正常,恢复为原来长文件名,程序报错,得出结论:长路径会导致os.path.getsize()函数无法找到文件
一、报错原因
在调试程序的时候发现,判断文件是否存在时无论使用os.path.getsize()还是os.path.exists(),其都是在使用os.stat()函数进行判断,并会导致OSError异常,进而返回FileNotFoundError
查询资料后发现,是因为在 Windows API中,路径的最大长度为 MAX_PATH,定义为 260 个字符,所以是因为路径过长导致了报错
二、解决方案
为了规避系统的路径长度限制,可以使用 \\\\?\\
或 \\\\?\\UNC\\
前缀来告诉系统使用更长的路径。
def count_folder_size(file_path):
# 计算文件夹的大小
total_size_byte = 0
for root, dirs, files in os.walk(file_path):
for file in files:
file_path = os.path.join(root, file).replace("\\", "/")
# 处理长路径问题。在 Windows 文件系统中,对于一些特别长的路径,可能会超出系统的路径长度限制,路径的最大长度为 260 个字符,
# https://learn.microsoft.com/zh-cn/windows/win32/fileio/maximum-file-path-limitation?tabs=registry
# 在UTF-8编码中,一个汉字通常占用3个字节。所以如果路径是纯粹的汉字组成,并且使用UTF-8编码,260个字符的路径大致可以包含 260 / 3 = 86 个汉字。
if len(file_path) > 85:
file_path = os.path.abspath(file_path)
if file_path.startswith(u"\\\\"):
# 检查路径是否以 \\ 开头,判断是否是网络路径(UNC 路径)。
# 如果路径是 UNC 路径,使用 path=u"\\\\?\\UNC\\"+path[2:] 来添加前缀 \\\\?\\UNC\\。这个前缀告诉系统使用更长的路径。
file_path = u"\\\\?\\UNC\\" + file_path[2:]
else:
# 如果路径不是 UNC 路径,使用 path=u"\\\\?\\"+path 来添加前缀 \\\\?\。同样,这个前缀告诉系统使用更长的路径。
file_path = u"\\\\?\\" + file_path
total_size_byte += os.stat(file_path).st_size
return total_size_byte
三、参考链接
- 最大路径长度限制 - Win32 apps | Microsoft Learn
- python - Pathname too long to open? - Stack Overflow
- Long paths for python on windows - os.stat() fails for relative paths? (appsloveworld.com)
- Built-in Exceptions — Python 3.9.17 documentation
- stat --- 解析 stat() 结果 — Python 3.12.1 文档
- Python os.stat() 方法 | 菜鸟教程 (runoob.com)