zoukankan      html  css  js  c++  java
  • 【JAVA】遍历打印目录结构

    给定一个目录,打印出该目录包含的目录或者文件的结构来,文件和其父目录之间通过缩进来表示父子关系。

    比如:

    0 Test$
    --1 src$
    ----2 TravelDir.java
    ----2 pms$

    0 Test$

    --1 src$

    ----2 TravelDir.java

    ----2 pms$

    --1 bin$

    表示Test目录下有两个目录:src和bin,src目录里有一个文件TravelDir.java和一个目录pms。(目录名字后面带$,文件不带)


    其实遍历打印目录结构,就是对目录这个”树结构“进行遍历,按照上述结构的话,应该是采用深度优先遍历。


    为了完成对特定文件名字的筛选,首先定义一个文件名字过滤接口:(策略模式?O(∩_∩)O)

     

    FileNameFilter
    1 interface FileNameFilter{
    2 boolean accept(String filename);
    3 }

    1)采用递归实现

    代码
     1 /*
     2      * 参数:root:要遍历的文件,
     3          *spanToLeft:距离左边的空白或者分隔符数目,
     4          *spanChar:空白字符, 
     5          *filter:根据条件选择文件
     6      * 
     7      */
     8     private void travel(File root, int spanToLeft, char spanChar,
     9             FileNameFilter filter) {
    10         spanToLeft += 4;
    11         if (root.isFile()) {
    12             String name = root.getName();
    13             if (filter.accept(name)) {
    14                 for (int k = 0; k < spanToLeft; k++) {
    15                     strDir.append(spanChar);
    16                 }
    17                 strDir.append(root.getName() + "\r\n");
    18                 fileCount++;
    19             }
    20         } else if (root.isDirectory()) {
    21             for (int k = 0; k < spanToLeft; k++) {
    22                 strDir.append(spanChar);
    23             }
    24             strDir.append(root.getName() + "$\r\n");
    25             dirCount++;
    26             File[] children = root.listFiles();
    27             if (children == null)
    28                 return;
    29             for (int i = 0; i < children.length; i++) {
    30                 travel(children[i], spanToLeft, spanChar, filter);
    31             }
    32         }
    33     }
    34     
    35     public void travelDir(File root, int spanToLeft, char spanChar,
    36             FileNameFilter filter){
    37         if (root == null)
    38             return;
    39         if (!root.exists()) {
    40             System.err.println("file " + root.getName() + " does not exist!");
    41             return;
    42         }
    43         travel(root, spanToLeft, spanChar, filter);
    44         

    45     } 

    2)采用非递归实现(用堆栈)

    为了保存每个文件的层次信息,定义一个类,保存文件名和层次信息
    FileDesc
    1 class FileDesc {
    2     public String filename;
    3     public int fileindex;
    4 
    5     public FileDesc(String name, int index) {
    6         filename = name;
    7         fileindex = index;
    8     }

    9 } 

    非递归代码:

    非递归代码
     1 public ArrayList<FileDesc> travelWithStack(File root, FileNameFilter filter) {
     2         ArrayList<FileDesc> res = new ArrayList<FileDesc>();
     3         if (root == null)
     4             return res;
     5         Stack<File> stack = new Stack<File>();
     6         Stack<Integer> stack1 = new Stack<Integer>();
     7         stack.push(root);
     8         stack1.add(0);
     9         while (!stack.empty()) {
    10             File file = stack.pop();
    11             int iii = stack1.pop();
    12             if (file.isDirectory()) {
    13                 FileDesc desc = new FileDesc(file.getName() + "$", iii);
    14                 res.add(desc);
    15                 dirCount++;
    16                 File[] children = file.listFiles();
    17                 if (children == null)
    18                     continue;
    19                 for (int i = 0; i < children.length; i++) {
    20                     stack.push(children[i]);
    21                     stack1.push(iii + 1);
    22                 }
    23             } else if (file.isFile()) {
    24                 String filename = file.getName();
    25                 if (filter.accept(filename)) {
    26                     FileDesc desc = new FileDesc(filename, iii);
    27                     res.add(desc);
    28                     fileCount++;
    29                 }
    30             }
    31         }
    32         return res;

    33     } 

    当初学数据结构的时候,学到树遍历那一章,感觉用递归实现遍历,无论是深度优先还是广度优先(注:转成非递归,深度优先用堆栈,广度优先用队列),代码都比较简单而且容易理解。那时候听说非递归实现很难实现,因此连敢看都没敢看,其实那本书也提供了伪代码。但当时感觉还是不怎么明白,也没怎么仔细看。所以一直以来觉得递归转非递归很难,而且也没怎么实际写过代码。前段时间去参加一个单位的笔试题,里面就有一道题要求用非递归实现二叉树的先序遍历,呵呵,说实话,以前还真没怎么写过,都是用递归。于是在考场时试着写了一下,没想到仔细理了一下思路,很快就写出来了,其实没想象中那么难。最近也在研究了一下算法,感觉还是很有意思的,以前总觉得算法很深奥,其实现在想想,没那么高深,关键不能只是在想,要亲自去试试。

    ps:也许很多事情没我们想象的那么复杂,亲自去尝试一下,你不去尝试怎么知道自己不行呢。。。
     
    其实写这个程序主要有一个目的,就是想统计一下我电脑里的音乐文件夹下面的音乐文件。以下是我用程序输出的结果(直接输出到文件里):
    对音乐感兴趣的朋友可以下来看看,丰富你的音乐库,哈哈
  • 相关阅读:
    53. Maximum Subarray
    64. Minimum Path Sum
    28. Implement strStr()
    26. Remove Duplicates from Sorted Array
    21. Merge Two Sorted Lists
    14. Longest Common Prefix
    7. Reverse Integer
    412. Fizz Buzz
    linux_修改域名(centos)
    linux_redis常用数据类型操作
  • 原文地址:https://www.cnblogs.com/gaojing/p/1614875.html
Copyright © 2011-2022 走看看