python模块代码
import os
import json
import xml.etree.ElementTree as ET
from typing import List, Optional, Dict, Union
from pathlib import Path class DirectoryTreeExporter:def __init__(self,root_path: str,output_file: str,fmt: str = 'txt',show_root: bool = True,include_hidden_files: bool = False,include_hidden_dirs: bool = False,folders_only: bool = False,allowed_extensions: Optional[List[str]] = None):"""参数说明:- root_path: 要扫描的根目录路径 - output_file: 输出文件路径 - fmt: 输出格式(txt/json/xml)- show_root: 是否显示根目录为树的顶层节点 - include_hidden_files: 是否包含隐藏文件 - include_hidden_dirs: 是否包含隐藏文件夹 - folders_only: 是否仅显示文件夹 - allowed_extensions: 允许的文件扩展名列表(例如 ['.py', '.txt'])"""self.root = Path(root_path).resolve()self.output_file = output_file self.fmt = fmt.lower() self.show_root = show_root self.include_hidden_files = include_hidden_files self.include_hidden_dirs = include_hidden_dirs self.folders_only = folders_only self.allowed_extensions = set(allowed_extensions or [])def _is_hidden(self, path: Path) -> bool:"""跨平台的隐藏文件/目录检测"""if os.name == 'nt': hidden_attr = os.stat(path).st_file_attributes return hidden_attr & 2 else: return path.name.startswith('.') def _should_include(self, path: Path, is_dir: bool) -> bool:"""过滤条件判断"""if is_dir:if not self.include_hidden_dirs and self._is_hidden(path):return False else:if not self.include_hidden_files and self._is_hidden(path):return False if self.folders_only and not is_dir:return False if not is_dir and self.allowed_extensions: return path.suffix.lower() in self.allowed_extensions return True def _build_tree(self, node: Path, tree_dict: Dict) -> None:"""递归构建树形结构"""for child in node.iterdir(): if not self._should_include(child, child.is_dir()): continue entry = {'name': child.name, 'type': 'directory' if child.is_dir() else 'file','children': []}if child.is_dir(): self._build_tree(child, entry)tree_dict['children'].append(entry)def generate(self) -> None:"""生成并导出目录树"""tree = {'name': self.root.name, 'type': 'directory','children': []} if self.show_root else {'children': []}if self.show_root: self._build_tree(self.root, tree)else:for child in self.root.iterdir(): if self._should_include(child, child.is_dir()): entry = {'name': child.name, 'type': 'directory' if child.is_dir() else 'file','children': []}if child.is_dir(): self._build_tree(child, entry)tree['children'].append(entry)output_methods = {'txt': self._generate_txt,'json': self._generate_json,'xml': self._generate_xml }if self.fmt not in output_methods:raise ValueError(f"不支持的格式: {self.fmt}") output_methods[self.fmt](tree)def _generate_txt(self, tree: Dict) -> None:"""生成文本树形结构"""def _recurse(node: Dict, depth: int, lines: List[str], is_last: bool) -> None:prefix = ""if depth > 0:prefix = "│ " * (depth - 1) + ("└── " if is_last else "├── ")lines.append(f"{prefix}{node['name']} ({node['type']})")children = node.get('children', [])for i, child in enumerate(children):_recurse(child, depth + 1, lines, i == len(children)-1)lines = []if self.show_root: _recurse(tree, 0, lines, True)else:for child in tree['children']:_recurse(child, 0, lines, False)lines = self.replace_vertical_below_lconnector(lines)with open(self.output_file, 'w', encoding='utf-8') as f:f.write("\n".join(lines)) def _generate_json(self, tree: Dict) -> None:"""生成JSON结构"""with open(self.output_file, 'w', encoding='utf-8') as f:json.dump(tree, f, indent=2, ensure_ascii=False)def _generate_xml(self, tree: Dict) -> None:"""生成XML结构"""def _add_node(parent: ET.Element, node: Dict) -> None:elem = ET.SubElement(parent, node['type'])elem.set('name', node['name'])for child in node.get('children', []):_add_node(elem, child)root = ET.Element('directory_tree')if self.show_root: _add_node(root, tree)else:for child in tree['children']:_add_node(root, child)tree = ET.ElementTree(root)tree.write(self.output_file, encoding='utf-8', xml_declaration=True)
if __name__ == "__main__":exporter = DirectoryTreeExporter(root_path=r"D:\Creation\JiLeiFunc\root_dir",output_file=r"D:\Creation\JiLeiFunc\tree.txt", fmt="txt",show_root=True,include_hidden_files=False,folders_only=False )exporter.generate()