陈池 發表於 2025-9-4 11:25:00

突破层级壁垒:Java通过递归实现目录结构的扁平化解析

<p>@</p><div class="toc"><div class="toc-container-header">目录</div><ul><li>前言</li><li>简介</li><li>一、 定义核心接口</li><li>二、实现接口逻辑</li><li>三、创建测试类</li><li>四、验证结果</li><li>总结</li></ul></div><p></p>
<hr>
<h1 id="前言">前言</h1>
<p><font color="#999AAA">请各大网友尊重本人原创知识分享,谨记本人博客:南国以南i、</font>微信公众号:<strong>白码梦想家</strong></p>
<hr style="border: solid; width: 100px; height: 1px" color="#000000" size="1&quot;">
<p><code>提示:以下是本篇文章正文内容,下面案例可供参考</code></p>
<h1 id="简介">简介</h1>
<p>在日常 Java 开发中,我们经常会遇到<strong>目录遍历与路径收集的需求</strong> —— 比如统计某个文件夹下的所有配置文件、导出目录结构到文档,或是批量处理特定路径下的文件。但传统实现往往存在痛点:要么只打印路径不保存,要么层级关系混乱,要么异常处理不完善。实现 <strong>「指定路径递归遍历、层级清晰标注、路径收集到 List 返回」</strong> 的完整功能</p>
<h1 id="一-定义核心接口">一、 定义核心接口</h1>
<p><font color="#FF0000">注意</font>:首先定义接口,明确对外提供的功能</p>
<pre><code class="language-java">import java.io.IOException;
import java.util.List;

/**
* .
* 文件路径收集接口
* 定义核心功能:接收路径,返回包含所有文件/文件夹路径的List(带层级信息)
*/
public interface FilePathPrinter {

    /**
   * .
   * 收集指定路径下的所有文件路径和递归子文件夹路径
   * @param path 目标文件夹路径(支持相对路径和绝对路径)
   * @return List&lt;String&gt; 包含层级信息的路径列表
   * @throws IllegalArgumentException 当路径为空、不存在或非目录时抛出
   * @throws IOException 当文件读取过程中发生IO错误时抛出(如权限不足)
   */
    List&lt;String&gt; collectFilePaths(String path) throws IllegalArgumentException, IOException;
}
</code></pre>
<h1 id="二实现接口逻辑">二、实现接口逻辑</h1>
<p><font color="#FF0000">注意</font>:功能实现包含: <strong>「参数校验」「递归遍历」「层级格式化」「路径收集」</strong></p>
<pre><code class="language-java">import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* .
* 文件路径收集接口的实现类
* 负责具体的路径遍历、层级处理和结果收集逻辑
*/
public class FilePathPrinterImpl implements FilePathPrinter {

    // 定义文件夹层级的前缀符号(静态常量,便于统一修改)
    private static final String FOLDER_PREFIX = "└── ";
    private static final String LEVEL_INDENT = "│";

    /**
   * .
   * 核心实现:收集指定路径下的所有文件和文件夹路径
   */
    @Override
    public List&lt;String&gt; collectFilePaths(String path) throws IllegalArgumentException, IOException {
      // 1. 参数校验:先处理非法输入,避免后续逻辑崩溃
      if (path == null || path.trim().isEmpty()) {
            throw new IllegalArgumentException("路径不能为空!");
      }

      File rootDir = new File(path);
      // 校验路径是否存在
      if (!rootDir.exists()) {
            throw new IllegalArgumentException("指定路径不存在:" + path);
      }
      // 校验路径是否为目录(不是文件)
      if (!rootDir.isDirectory()) {
            throw new IllegalArgumentException("指定路径不是目录:" + path);
      }

      // 2. 初始化List,用于存储最终的路径结果
      List&lt;String&gt; pathList = new ArrayList&lt;&gt;();

      // 3. 递归遍历根目录(根目录层级为1)
      traverseDirectory(rootDir, 1, pathList);

      // 4. 返回收集好的路径列表
      return pathList;
    }

    /**
   * .
   * 递归遍历目录的核心方法
   * @param currentDir 当前要遍历的目录
   * @param level 当前目录的层级(根目录为1)
   * @param pathList 用于收集路径的List
   */
    private void traverseDirectory(File currentDir, int level, List&lt;String&gt; pathList) throws IOException {
      // 获取当前目录下的所有文件/文件夹(注意:listFiles()可能返回null,需处理)
      File[] files = currentDir.listFiles();
      if (files == null) {
            // 当目录无法访问时(如权限不足),添加提示信息到List,不抛出异常(避免中断整体遍历)
            String inaccessibleMsg = getLevelIndicator(level) + "[无法访问的目录] " + currentDir.getCanonicalPath();
            pathList.add(inaccessibleMsg);
            return;
      }

      // 遍历当前目录下的每个文件/文件夹
      for (File file : files) {
            if (file.isFile()) {
                // 处理文件:添加「文件类型+绝对路径」到List(文件无需层级符号,只需显示层级)
                String fileInfo = String.format("第%d层 [文件] %s", level, file.getCanonicalPath());
                pathList.add(fileInfo);
            } else if (file.isDirectory()) {
                // 处理文件夹:先添加「文件夹类型+层级符号+绝对路径」到List
                String folderPrefix = getLevelIndicator(level) + FOLDER_PREFIX;
                String folderInfo = String.format("第%d层 [文件夹] %s%s",
                        level, folderPrefix, file.getCanonicalPath());
                pathList.add(folderInfo);

                // 递归遍历子文件夹(层级+1)
                traverseDirectory(file, level + 1, pathList);
            }
      }
    }

    /**
   * .
   * 根据层级生成缩进符号(可视化层级关系)
   * @param level 当前层级
   * @return 层级对应的缩进字符串(如第2层返回「│」,第3层返回「││」)
   */
    private String getLevelIndicator(int level) {
      // 根目录(level=1)无需缩进,从第2层开始添加缩进
      if (level &lt;= 1) {
            return "";
      }
      // 层级-1个LEVEL_INDENT(因为第2层需要1个缩进,第3层需要2个,以此类推)
      StringBuilder indent = new StringBuilder();
      for (int i = 1; i &lt; level; i++) {
            indent.append(LEVEL_INDENT);
      }
      return indent.toString();
    }
}
</code></pre>
<h1 id="三创建测试类">三、创建测试类</h1>
<pre><code class="language-java">import java.io.IOException;
import java.util.List;

/**
* .
* 文件路径收集功能的演示类
* 展示如何调用接口,处理结果,并捕获异常
*/
public class FilePathPrinterDemo {
    public static void main(String[] args) {
      // 1. 创建接口实现类实例
      FilePathPrinter pathPrinter = new FilePathPrinterImpl();
      // 2. 测试路径(根据系统修改,支持相对路径和绝对路径)
      String testPath;
      // Windows系统示例:C:/Users/YourName/Documents
      // Linux/Mac系统示例:/home/yourname/documents
      testPath = "."; // 当前工作目录
      try {
            // 3. 调用核心方法,收集路径
            List&lt;String&gt; collectedPaths = pathPrinter.collectFilePaths(testPath);

            // 4. 处理结果:打印统计信息和所有路径
            System.out.println("=== 路径收集结果 ===");
            System.out.println("目标路径:" + new File(testPath).getCanonicalPath());
            System.out.println("收集到的路径总数:" + collectedPaths.size());
            System.out.println("-------------------");
            for (String path : collectedPaths) {
                System.out.println(path);
            }

      } catch (IllegalArgumentException e) {
            // 处理参数错误(如路径不存在、非目录)
            System.err.println("参数错误:" + e.getMessage());
      } catch (IOException e) {
            // 处理IO错误(如文件读取失败)
            System.err.println("文件处理错误:" + e.getMessage());
      }
    }
}
</code></pre>
<h1 id="四验证结果">四、验证结果</h1>
<pre><code class="language-java">=== 路径收集结果 ===
目标路径:D:\JavaProjects\FileDemo
收集到的路径总数:8
-------------------
第1层 [文件] D:\JavaProjects\FileDemo\README.md
第1层 [文件] D:\JavaProjects\FileDemo\pom.xml
第1层 [文件夹] └── D:\JavaProjects\FileDemo\src
第2层 [文件夹] │└── D:\JavaProjects\FileDemo\src\main
第3层 [文件夹] ││└── D:\JavaProjects\FileDemo\src\main\java
第4层 [文件] │││└── D:\JavaProjects\FileDemo\src\main\java\FilePathPrinter.java
第4层 [文件] │││└── D:\JavaProjects\FileDemo\src\main\java\FilePathPrinterImpl.java
第4层 [文件] │││└── D:\JavaProjects\FileDemo\src\main\java\FilePathPrinterDemo.java
</code></pre>
<hr style="border: solid; width: 100px; height: 1px" color="#000000" size="1&quot;">
<h1 id="总结">总结</h1>
<p>我是南国以南i记录点滴每天成长一点点,学习是永无止境的!转载请附原文链接!!!</p><br><br>
来源:https://www.cnblogs.com/bgyb/p/19073196
頁: [1]
查看完整版本: 突破层级壁垒:Java通过递归实现目录结构的扁平化解析