在前面所讲内容 JavaSE第八十八讲:递归详解以及递归在阶乘与斐波那契数列的使用 中后面留下了一个递归的作业
递归作业:给定任意一个目录,以树形方式展现出该目录中的所有子目录和文件。另外,在展现的时候将目录排在上面,文件排在下面。每一层要加上缩进。
现在我们就来讲解这一个作业
编译执行结果成功输出"D:\app\test"目录下的文件资源树。package com.ahuier.io; import java.io.File; import java.util.ArrayList; public class ListAllTest { private static int time; // 用户判读目录或文件所处的层次 /* * 递归方法 接受一个需要展开的文件目录 */ public static void deepList(File file) { /* * 递归的出口:当遍历到文件时,或者遍历到目录同时这个目录为空的时候 */ if (file.isFile() || 0 == file.listFiles().length) { return; } /* * 当遇到目录并且目录中子目录或者有文件的时候 注意这边遇到目录时,必须先显示当前目录下的目录和文件,然后再去遍历子目录 */ else { File[] files = file.listFiles(); files = sort(files); // 将返回过来的排完序的新的数组赋给原有的数组,则原有的数组就是排序过的了 for (File f : files) { StringBuffer output = new StringBuffer(); /* * 遍历数组,如果是一个文件的话,则将其打印出来,注意再打印的时候要有一个缩进, * 这个缩进具体缩多少个tab键是根据此时目录与指定目录的层数决定的。 所以是缩进 + 文件的形式打印出来的 */ if (f.isFile()) { output.append(getTabs(time)); // 增加多少层的tab键个数 output.append(f.getName()); // 增加文件名 } // 将当前目录输出 else { output.append(getTabs(time)); output.append(f.getName()); output.append("\\"); } System.out.println(output); // 如果目录里面有子目录,则继续递归 if (f.isDirectory()) { time++; deepList(f); time--; } } } } /* * 整理文件数组,使得目录排在文件之前 使用ArrayList先进先出的特性,先装目录,再装文件 * 这样整个数组输出的时候就可以使得目录排在前面,文件排在后面 */ private static File[] sort(File[] files) { ArrayList<File> sorted = new ArrayList<File>(); // 遍历这个文件数组,如果是目录则把目录装进数组里面 for (File f : files) { if (f.isDirectory()) { sorted.add(f); } } // 遍历这个文件数组,如果是文件则把文件装进数组里面 for (File f : files) { if (f.isFile()) { sorted.add(f); } } /* * 注意这边返回的是一个新的数组,这个新的新组是排完序后的数组 * 这边我们没有对原数组进行操作,因为我们不确定原数组是否被程序其他地方所用。所以返回一个新的数组 集合转数组用 toArry()方法 * 如果是数组转集合就用 Arrys的 asList()方法 */ return sorted.toArray(new File[files.length]); } // 判断需要加多少tab的方法,就是判断缩进的层数, time表示层数 private static String getTabs(int time) { StringBuffer buffer = new StringBuffer(); for (int i = 0; i < time; i++) { buffer.append("\t"); } return buffer.toString(); } public static void main(String[] args) { File file = new File("D:/app/test"); deepList(file); } }
【说明】:在编译过程中我们要学会Eclipse的调试功能
调试的快捷键:
(Step Into) F5 :进入某个函数内部调试
(Step Over) F6 :不进入函数内部调试
(Step Return)F7 : 返回
(Resume) F8 :跳过这一个断点,直接执行下一个断点。