Windows Server 2012运行Python目录遍历代码报FileNotFoundError[WinError3]求助
问题描述
我编写了如下代码,用于遍历指定路径下的所有文件、子文件夹及各级目录,但是在Windows Server 2012设备上运行时持续抛出FileNotFoundError[WinError3]报错。值得注意的是,我在Mac设备上运行同一段代码时也出现过相同报错,将follow_symlinks参数设置为False后报错就消失了,但该配置在Windows Server 2012环境下没有解决问题,恳请各位帮忙排查代码存在的问题。
原始代码
from pathlib import Path import csv import os import time from datetime import datetime class File: def __init__(self, folder_path): self.folder_path = Path(folder_path) def folders(self): return [folder for folder in self.folder_path.iterdir() if folder.is_dir()] def summary(self): errors = [] data_table = [] folders = self.folders() for folder in folders: total=0 count = 0 files = folder.glob('**/*') for file in files : try: total+=(os.stat(file, follow_symlinks=False).st_size) count+=1 except OSError as e: errors.append(f'Error with file {file} in folder {folder} Error-->{e}') lm_date = datetime.strftime(datetime.strptime(time.ctime(os.stat(folder).st_mtime), '%a %b %d %H:%M:%S %Y'), '%d-%b-%Y') data_table.append({'Path':folder, 'Size in MB':f'{total/1048576}', 'File Count':count, 'Last Modifed Date':lm_date}) lm_date = datetime.strftime(datetime.strptime(time.ctime(os.stat(folder).st_mtime), '%a %b %d %H:%M:%S %Y'), '%d-%b-%Y') data_table.append({'Path':folder, 'Size in MB':f'{total/1048576}', 'File Count':count, 'Last Modifed Date':lm_date}) return {'data':data_table, 'error':errors} def csv_export(self, file_path): data_list = self.summary()['data'] headers = data_list[0].keys() with open(file_path, 'w') as fp: writer = csv.DictWriter(fp, headers) writer.writeheader() try: for data in data_list: writer.writerow(data) print(f'file saved to location: {os.path.join(os.getcwd(), file_path)}') except OSError as e: print(f'Error exporting data file {e}')
问题排查与修复
核心问题原因
你遇到的WinError3报错是Windows系统特有的路径长度限制问题:Windows Server 2012默认开启260字符的路径长度上限,当遍历到路径总长度超过260的文件/文件夹时,系统会直接抛出路径不存在的错误,和符号链接无关,所以设置follow_symlinks自然不会生效。
另外你的代码还有两处逻辑问题:
- 捕获异常时错误地把不完整的统计数据追加到了结果列表里,会导致同一个文件夹产生多条重复的无效记录
- 重复调用
os.stat(folder)没有做异常捕获,遇到无权限访问的文件夹时也会触发报错 - 时间转换逻辑冗余,
time.ctime受系统语言影响,非英文语言的Windows设备上会出现格式匹配错误
修复方案
- **开启Windows长路径支持(可选)
如果希望全局开启长路径支持,操作步骤如下:
- 按下Win+R输入
regedit打开注册表 - 定位到路径
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\FileSystem - 找到名为
LongPathsEnabled的DWORD值,将值设置为1,重启设备生效
- **代码层面修复
无需修改系统设置也可以通过路径前缀兼容长路径,优化后代码如下:
from pathlib import Path import csv import os from datetime import datetime class FileScanner: def __init__(self, folder_path): # 路径前加\\?\前缀强制Windows识别最长32767字符的长路径 raw_path = Path(folder_path).resolve() self.folder_path = Path(f'\\\\?\\{raw_path}') def folders(self): folders = [] for item in self.folder_path.iterdir(): try: if item.is_dir(follow_symlinks=False): folders.append(item) except OSError as e: print(f"跳过无法访问的目录:{item}, 错误:{e}") return folders def summary(self): errors = [] data_table = [] folders = self.folders() for folder in folders: total=0 count = 0 files = folder.glob('**/*') for file in files : try: if file.is_file(follow_symlinks=False): total += os.stat(file, follow_symlinks=False).st_size count +=1 except OSError as e: errors.append(f'处理文件 {file} 时出错,所属文件夹 {folder},错误信息:{e}') # 文件夹统计完成后再统一追加记录,避免异常时写入无效数据 try: mtime = folder.stat(follow_symlinks=False).st_mtime lm_date = datetime.fromtimestamp(mtime).strftime('%d-%b-%Y') data_table.append({ 'Path': str(folder).replace('\\\\?\\', ''), # 输出时移除长路径前缀 'Size in MB': f'{total/1048576:.2f}', 'File Count': count, 'Last Modifed Date': lm_date }) except OSError as e: errors.append(f'读取文件夹 {folder} 元信息失败,错误信息:{e}') return {'data':data_table, 'error':errors} def csv_export(self, file_path): result = self.summary() data_list = result['data'] if not data_list: print("无有效数据可导出") return headers = data_list[0].keys() export_path = Path(file_path).resolve() try: # newline=''参数避免Windows下生成的CSV出现多余空行,utf-8-sig编码保证中文路径正常显示 with open(export_path, 'w', newline='', encoding='utf-8-sig') as fp: writer = csv.DictWriter(fp, headers) writer.writeheader() writer.writerows(data_list) print(f'文件已保存到:{export_path}') if result['error']: print(f"本次扫描共遇到{len(result['error'])}个错误,错误列表:") for err in result['error']: print(f"- {err}") except OSError as e: print(f'导出数据文件出错:{e}')
内容的提问来源于stack exchange,提问作者pyzer
相关产品推荐
相关产品推荐

