
本文详解如何用 python 的 `os.walk()` 安全遍历含非 ascii 字符(如西里尔文、希腊字母)的路径,并生成正确编码的目录结构文本文件,核心在于显式指定文件写入时的 utf-8 编码。
在使用 os.walk() 生成目录结构树时,若目标路径中存在 Unicode 文件名(例如俄语、希腊语、中文等),原始代码常会抛出 UnicodeEncodeError,典型错误信息如下:
UnicodeEncodeError: 'charmap' codec can't encode characters in position 4-11: character maps to
该异常并非源于 os.walk() 本身——Python 3 中 os.walk() 默认返回 str 类型的 Unicode 路径和文件名(内部以 UTF-8 表示),完全支持多语言字符。真正的问题出在文件写入环节:open(file_name, "w") 在未指定 encoding 参数时,会采用系统默认编码(Windows 上常为 cp1252,Linux/macOS 通常为 utf-8),而 cp1252 等传统编码无法表示绝大多数非拉丁字符,导致写入失败。
✅ 正确解法是:显式声明文件编码为 'utf-8'。修改后的健壮版本如下:
import os
def record_directory_structure(directory_path: str, file_name: str):
# ✅ 关键修复:强制使用 UTF-8 编码写入文件
with open(file_name, "w", encoding='utf-8') as file:
for root, dirs, files in os.walk(directory_path):
# 计算当前目录层级(相对于起始路径)
level = root.replace(directory_path, '').count(os.sep)
indent = ' ' * 4 * level
# 写入目录名(结尾加 '/')
file.write(f'{indent}{os.path.basename(root)}/\n')
# 子项缩进(比目录多一级)
subindent = ' ' * 4 * (level + 1)
# 按字典序排序文件,提升可读性(可选)
for f in sorted(files):
file.write(f'{subindent}{f}\n')? 使用示例:
漂亮的企业网站。NET2.0出来了, 本次升级修改如下: 1、优化了3层结构。 2、优化了后台管理代码,增强了安全性能。 3、增加了系统名称及关键字管理。 4、增加了系统错误日志记录,自动生成Systemlog.log日志文件。 备注:本系统采用ASP.NET 2.O+ACCESS开发,请调试的朋友安装.NET2.0运行环境! 网站内容 网站栏目包括 首页|企业简介|新闻中心|产品展示|公司展示|
record_directory_structure(r"C:\my_project", "structure.txt") # 或处理含西里尔文路径: record_directory_structure(r"D:\Проекты\Анализ", "структура.txt")
⚠️ 注意事项:
- 不要尝试对文件名做 encode('utf-8').decode('utf-8') 等无意义的编解码操作——这既不解决写入问题,还可能引入冗余或错误;
- 若需兼容旧版 Python(
- 生成的 .txt 文件可用 VS Code、Notepad++ 或现代系统记事本(启用 UTF-8 检测)正确查看,避免用老旧记事本直接打开(它可能误判编码);
- 如需增强可读性,可对 dirs 和 files 分别排序(例如 sorted(dirs)),使输出结构更稳定。
总结:处理国际化路径的核心原则是——读取靠 os.walk() 自动 Unicode 化,写入靠 open(..., encoding='utf-8') 显式保真。一句代码修正,即可彻底规避编码陷阱。









