导出指定文件夹下的文件结构 工具模块-Python

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,show_type_in_txt: bool = False):"""参数说明:- root_path: 要扫描的根目录路径 - output_file: 输出文件路径 - fmt: 输出格式(txt/json/xml)- show_root: 是否显示根目录为树的顶层节点 - include_hidden_files: 是否包含隐藏文件 - include_hidden_dirs: 是否包含隐藏文件夹 - folders_only: 是否仅显示文件夹 - allowed_extensions: 允许的文件扩展名列表(例如 ['.py', '.txt'])- show_type_in_txt: 在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 [])self.show_type_in_txt  = show_type_in_txtdef _is_hidden(self, path: Path) -> bool:"""跨平台的隐藏文件/目录检测"""if os.name  == 'nt':  # Windows系统 hidden_attr = os.stat(path).st_file_attributes  return hidden_attr & 2  # FILE_ATTRIBUTE_HIDDEN else:  # Unix-like系统 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 replace_vertical_below_lconnector(self, lines):"""清除多余的竖线"""for i in range(len(lines)):# if lines[i]:lines[i] = list(lines[i])# 遍历每一行,查找'└'符号位置sign_pos_1 = []for row in range(len(lines)):for col in range(len(lines[row])):if lines[row][col] == '└':sign_pos_1.append((row, col))# while col >= 0 and lines[row][col] != '│':#     lines[row][col] = ' '#     col -= 1for row in range(len(lines)):for col in range(len(lines[row])):for pos in sign_pos_1:if row > pos[0] and col==pos[1]:if lines[row][col] == '│':lines[row][col] = '  '# lines[row].insert(0,' ')# sign_pos_1.insert(0)for i in range(len(lines)):lines[i] = ''.join(lines[i])return linesdef _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']})")if self.show_type_in_txt:lines.append(f"{prefix}{node['name']}  ({node['type']})")else:lines.append(f"{prefix}{node['name']}")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", root_path=r"D:\test\root_dir",output_file=r"D:\test\tree.txt", fmt="txt",show_root=True,include_hidden_files=False,folders_only=False # ,# allowed_extensions=['.py', '.txt'])exporter.generate() 

运行效果截图

*.txt 文档

在这里插入图片描述
标注节点类型:
在这里插入图片描述

*.json 文档

在这里插入图片描述

*.xml 文档

在这里插入图片描述

功能特性说明

1. 多格式支持

  • 文本格式:使用ASCII字符构建树状结构
    project (directory)
    ├── src (directory)
    │   ├── main.py (file)
    │   └── utils.py (file)
    └── README.md (file)
    
  • JSON格式:结构化数据存储,支持程序解析
    {"name": "project","type": "directory","children": [{"name": "src","type": "directory","children": [...]}]
    }
    
  • XML格式:标准数据交换格式,便于其他系统处理
    <directory_tree><directory name="project"><directory name="src">...</directory></directory>
    </directory_tree>
    

2. 智能过滤系统

  • 隐藏文件处理:自动识别操作系统类型(Windows/Unix)
  • 扩展名过滤:支持白名单机制(如仅显示.py和.txt)
  • 目录模式:通过folders_only=True仅展示文件夹结构

3. 跨平台兼容

  • 使用pathlib模块统一处理路径差异
  • 自动识别不同系统的隐藏文件判断逻辑

4. 性能优化

  • 递归算法优化:采用尾递归设计避免栈溢出
  • 内存管理:使用生成器模式构建大型目录树

扩展性设计

1. 添加新格式

class EnhancedDirectoryTreeExporter(DirectoryTreeExporter):def _generate_markdown(self, tree: Dict) -> None:"""新增Markdown格式支持"""def _recurse(node, depth):indent = "  " * depth line = f"{indent}- {node['name']}"if node['type'] == 'file':line += f" `{node['type']}`"yield line for child in node.get('children', []):yield from _recurse(child, depth+1)lines = list(_recurse(tree, 0)) if self.show_root else []with open(self.output_file, 'w') as f:f.write("\n".join(lines))def generate(self):self.output_methods['md'] = self._generate_markdown super().generate()

2. 自定义渲染

exporter = DirectoryTreeExporter(...)
exporter.output_methods['custom'] = lambda tree: ...  # 动态添加渲染器 

典型应用场景

1. 项目文档生成

exporter = DirectoryTreeExporter(root_path=".",output_file="PROJECT_STRUCTURE.md",fmt="txt",allowed_extensions=['.py', '.md'],folders_only=False 
)

2. 系统审计

exporter = DirectoryTreeExporter(root_path="/var/log",output_file="system_logs.json",fmt="json",include_hidden_dirs=True,include_hidden_files=True 
)

3. 自动化部署

# 生成Docker镜像内的文件结构 
exporter = DirectoryTreeExporter(root_path="/app",output_file="docker_files.xml",fmt="xml",show_root=False 
)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/20962.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

PyCharm Terminal 自动切换至虚拟环境

PyCharm 虚拟环境配置完毕后&#xff0c;打开终端&#xff0c;没有跟随虚拟环境切换&#xff0c;如图所示&#xff1a; 此时&#xff0c;需要手动将终端切换为 Command Prompt 模式 于是&#xff0c;自动切换至虚拟环境 每次手动切换&#xff0c;比较麻烦&#xff0c;可以单…

Vue 实现通过URL浏览器本地下载 PDF 和 图片

1、代码实现如下&#xff1a; 根据自己场景判断 PDF 和 图片&#xff0c;下载功能可按下面代码逻辑执行 const downloadFile async (item: any) > {try {let blobUrl: any;// PDF本地下载if (item.format pdf) {const response await fetch(item.url); // URL传递进入i…

【前端】使用WebStorm创建第一个项目

文章目录 前言一、步骤1、启动2、创建项目3、配置Node.js4、运行项目 二、Node.js介绍 前言 根据前面文章中记录的步骤&#xff0c;已经安装好了WebStorm开发软件&#xff0c;接下来我们就用这个IDE开发软件创建第一个项目。 一、步骤 1、启动 启动软件。 2、创建项目 新建…

遥感与GIS在滑坡、泥石流风险普查中的实践技术应用

原文>>> 遥感与GIS在滑坡、泥石流风险普查中的实践技术应用 我国是地质灾害多发国家&#xff0c;地质灾害的发生无论是对于地质环境还是人类生命财产的安全都会带来较大的威胁&#xff0c;因此需要开展地质灾害风险普查。利用遥感&#xff08;RS&#xff09;技术进行地…

EasyExcel 自定义头信息导出

需求&#xff1a;需要在导出 excel时&#xff0c;合并单元格自定义头信息(动态生成)&#xff0c;然后才是字段列表头即导出数据。 EasyExcel - 使用table去写入&#xff1a;https://easyexcel.opensource.alibaba.com/docs/current/quickstart/write#%E4%BD%BF%E7%94%A8table%E…

QT异步编程之QMetaObject::invokeMethod

一、概述 1、QMetaObject::invokeMethod是Qt的一个功能强大的方法&#xff0c;它用于动态地调用一个对象地槽函数或成员函数。 2、这个方法允许你在运行时通过对象地元对象系统调用函数&#xff0c;而无需直接使用函数指针或其它静态机制。 3、元对象系统是一个基于C的扩展…

斐波那契数列模型:在动态规划的丝绸之路上追寻斐波那契的足迹(上)

文章目录 引言递归与动态规划的对比递归解法的初探动态规划的优雅与高效自顶向下的记忆化搜索自底向上的迭代法 性能分析与比较小结 引言 斐波那契数列&#xff0c;这一数列如同一条无形的丝线&#xff0c;穿越千年时光&#xff0c;悄然延续其魅力。其定义简单而优美&#xff…

php 系统命令执行及绕过

文章目录 php的基础概念php的基础语法1. PHP 基本语法结构2. PHP 变量3.输出数据4.数组5.超全局变量6.文件操作 php的命令执行可以执行命令的函数命令执行绕过利用代码中命令&#xff08;如ls&#xff09;执行命令替换过滤过滤特定字符串神技&#xff1a;利用base64编码解码的绕…

使用vscode调试transformers源码

简要介绍如何使用vscode调试transformers源码 以源码的方式安装transformers&#xff08;官方手册为Editable install&#xff09; 优先参考官方手册 git clone https://github.com/huggingface/transformers.git cd transformers pip install -e .以下展示transformers/exa…

macos安装jmeter测试软件

java环境安装 a. 验证安装环境 java -version # 如果有版本信息&#xff0c;说明已安装 b. 安装jdk # 安装 Homebrew&#xff08;如未安装&#xff09; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" # 安装 O…

2023年全国职业院校技能大赛GZ073网络系统管理赛项赛题第10套模块A:网络构建

​有问题请留言或主页私信咨询 2023年全国职业院校技能大赛 GZ073网络系统管理赛项 赛题第10套 模块A&#xff1a;网络构建 ​ ​ **目 **录 任务清单 &#xff08;一&#xff09;基础配置 &#xff08;二&#xff09;有线网络配置 &#xff08;三&#xff09;无线…

若依-@Excel新增注解numberFormat

Excel注解中原本的scale会四舍五入小数&#xff0c;导致进度丢失 想要的效果 显示的时候保留两个小数真正的数值是保留之前的数值 还原过程 若以中有一個專門的工具类&#xff0c;用来处理excel的 找到EXCEL导出方法exportExcel()找到writeSheet,写表格的方法找到填充数据的方法…

动静态链接与加载

目录 静态链接 ELF加载与进程地址空间&#xff08;静态链接&#xff09; 动态链接与动态库加载 GOT表 静态链接 对于多个.o文件在没有链接之前互相是不知到对方存在的&#xff0c;也就是说这个.o文件中调用函数的的跳转地址都会被设定为0&#xff08;当然这个函数是在其他.…

python-leetcode 33.排序链表

题目&#xff1a; 给定链表的头结点head,请将其按升序排列&#xff0c;并返回排序后的链表 方法一&#xff1a;自顶向下归并排序 链表自顶向下归并排序的过程&#xff1a; 1.找到链表的中点&#xff0c;以中点为分界&#xff0c;将链表拆分成两个子链表。寻找链表的中点可以…

PyQt加载UI文件

1.动态加载 import sys from PySide6 import QtCore,QtWidgets from PySide6.QtWidgets import * from PySide6.QtUiTools import QUiLoaderclass readfile(QWidget):def __init__(self):super().__init__()self.uiQUiLoader().load("test.ui",self) self.__c…

深入解析NoSQL数据库:从文档存储到图数据库的全场景实践

title: 深入解析NoSQL数据库:从文档存储到图数据库的全场景实践 date: 2025/2/19 updated: 2025/2/19 author: cmdragon excerpt: 通过电商、社交网络、物联网等12个行业场景,结合MongoDB聚合管道、Redis Stream实时处理、Cassandra SSTable存储引擎、Neo4j路径遍历算法等42…

EasyRTC:开启智能硬件与全平台互动新时代

在当今数字化时代&#xff0c;实时音视频互动已成为企业与用户沟通、协作和娱乐的关键技术。无论是在线教育、视频会议、远程医疗还是互动直播&#xff0c;流畅、高效的互动体验都是成功的关键。然而&#xff0c;实现跨平台、低延迟且功能丰富的音视频互动并非易事——直到 Eas…

【前端框架】vue2和vue3的区别详细介绍

Vue 3 作为 Vue 2 的迭代版本&#xff0c;在性能、语法、架构设计等多个维度均有显著的变革与优化。以下详细剖析二者的区别&#xff1a; 响应式系统 Vue 2 实现原理&#xff1a;基于 Object.defineProperty() 方法实现响应式。当一个 Vue 实例创建时&#xff0c;Vue 会遍历…

springboot-ffmpeg-m3u8-convertor nplayer视频播放弹幕 artplayer视频弹幕

学习链接 ffmpeg-cli-wrapper - 内部封装了操作ffmpeg命令的java类库&#xff0c;它提供了一些类和方法&#xff0c;可以方便地构建和执行 ffmpeg 命令&#xff0c;而不需要直接操作字符串或进程。并且支持异步执行和进度监听 springboot-ffmpeg-m3u8-convertor - gitee代码 …

Linux下centos系统中使用docker容器中的ollama下载deepseek速度太慢解决办法

以下是使用shell脚本实现的一个示例&#xff0c;该脚本会尝试下载一个名为"deepseek-r1:32b"的模型。通过每隔60秒中断一次下载操作&#xff0c;从何恢复下载速度。亲测有效,其中需要将模型改为你自己要下载的模型 #!/bin/bashwhile true; do# 检查模型是否已下载完…