递归:把大问题拆成很多小问题,然后再把小问题拆成更多的小问题,当我们把更多小问题解决了,小问题也解决了,随着小问题的解决,大问题也随之解决了
在方法本身不断的调用方法自己
递归注意事项:
递归一定要有出口,内存溢出
递归次数不宜过多,内存溢出
递归必须要有规则
案例1:从键盘接收一个文件夹路径,统计该文件夹大小
package com.digui.test; import java.io.File; import java.util.Scanner; public class Test01 { /** * 需求:从键盘接收一个文件夹路径,统计该文件夹大小 * 如何从键盘接收文件夹路径 * 1.创建键盘录入对象 * 2.定义一个无限循环 * 3.将键盘录入的结果存储并封装成File对象 * 4.对File对象判断 * 5.将文件夹路径对象返回 * * 如何统计文件夹大小呢?如果之间统计文件夹大小,结果为0. * 1.定义求和变量 * 2.获取文件夹下的所有文件和文件夹,listFiles()方法 * 3.遍历数组 * 4.判断是文件就计算大小并累加 * 4.判读是文件夹就递归调用 * * 分析: * 考虑递归需要一层一层的分析,并且有共性,可以嵌套 */ public static void main(String[] args) { File file = getDir(); long num = getFileLength(file); System.out.println(file+"文件大小为"+num); } /* * 如何统计文件夹大小 * 返回值类型:long * 参数列表:File file */ public static long getFileLength(File file) { long num = 0; File[] dir = file.listFiles(); for (File getDir : dir) { if(getDir.isFile()) { num = num + getDir.length(); }else { num = num + getFileLength(getDir); } } return num; } /* * 如何从键盘接收文件夹路径 * 返回值类型:File * 参数列表: */ public static File getDir() { Scanner sc = new Scanner(System.in); System.out.println("请输入文件夹路径"); while(true) { String len = sc.nextLine(); File file = new File(len); if(!file.exists()) { System.out.println("您输入的文件夹路径不存在,请输入正确的文件夹路径:"); }else if(file.isFile()) { System.out.println("您输入的是文件路径,请输入正确的文件夹路径:"); }else { return file; } } } }案例2:从键盘接收一个文件夹路径,删除该文件夹
package com.digui.test; import java.io.File; public class Test02 { /** * 需求:从键盘接收一个文件夹路径,删除该文件夹 * 从键盘接收一个文件夹路径 * 1.创建键盘录入对象 * 2.定义一个无限循环,循环控制条件是输入了正确的文件夹路径 * 3.将键盘录入的结果存储并封装成File对象 * 4.对File对象判断,是否是正确的文件夹路径 * 5.如果是文件夹路径,就将文件夹路径返回 * * 删除文件夹 * 1.获取该文件夹下的所有文件和文件夹 * 2.遍历数组 * 3.判断是文件就直接删除 * 4.如果是文件夹就递归调用 * 5.循环结束后.把空文件删除 */ public static void main(String[] args) { //调用键盘录入文件夹路径方法 File file = Test01.getDir(); //调用删除方法 deleteFile(file); } /* * 删除文件夹 * 返回值类型:void * 参数列表:File file */ public static void deleteFile(File file) { //1.获取该文件夹下的所有文件和文件夹 File[] subFiles = file.listFiles(); //遍历数组 for(int i=0; i<subFiles.length; i++) { //3.判断是文件就直接删除 if(subFiles[i].isFile()) { subFiles[i].delete(); //4.如果是文件夹就递归调用 }else { deleteFile(subFiles[i]); } } //5.循环结束后.把空文件删除 file.delete(); } }案例3:键盘接收两个文件夹路径,把其中一个文件夹中所有内容拷贝到另一个文件夹中
package com.digui.test; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; public class Test03 { /** * @param args * @throws IOException *需求:从键盘接收两个文件夹路径,把其中一个文件夹中所有内容拷贝到另一个文件夹中 *分析: *1.首先要在目标文件夹中创建一个原文件夹 *2.创建此抽象路径名指定的目录 *3.获取原文件夹中所有的文件和文件夹,存储在在File数组中 *4.遍历数组 *5.如果是文件就用IO流进行读写操作 *6.如果是文件夹就递归调用 * *问题:原则上是不能在同一个文件夹中进行拷贝本文件夹的操作的,这样会产生无限拷贝操作,直到最后内存溢出电脑蓝屏 * 所有在代码中要加入判断操作,如果是同文件夹拷贝就不让程序执行 */ public static void main(String[] args) throws IOException { //调用键盘录入文件夹路径方法 File src = Test01.getDir(); File dest = Test01.getDir(); if(src.getName().equals(dest.getName())){ System.out.println("目标文件夹是源文件的子文件夹"); }else { //调用拷贝方法 copyFiles(src,dest); } } public static void copyFiles(File src, File dest) throws IOException { //在目标文件夹中创建原文件夹 File newFiles = new File(dest, src.getName()); newFiles.mkdir(); //获取原文件夹中所有的文件和文件夹,存储在File数组中 File[] subFiles = src.listFiles(); //遍历数组 for (File subFile : subFiles) { //如果是文件就用IO流读写 if(subFile.isFile()) { BufferedInputStream bis = new BufferedInputStream(new FileInputStream(subFile)); BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(newFiles,subFile.getName()))); byte[] arr = new byte[1024*8]; int len; while((len=bis.read(arr))!=-1) { bos.write(arr, 0, len); } bos.close(); bis.close(); //如果是文件夹就递归调用,必须弄清楚原文件和目标文件的位置 }else { copyFiles(subFile, newFiles); } } } }案例4:从键盘接收一个文件夹路径,把文件夹中的所有文件和文件夹的名字按层级打印
package com.digui.test; import java.io.File; public class Test04 { /** * @param args * 需求:从键盘接收一个文件夹路径,把文件夹中的所有文件和文件夹的名字按层级打印 */ public static void main(String[] args) { //调用键盘录入文件夹路径方法 File file = Test01.getDir(); //调用打印方法 printDir(file,0); } //问题,并没有对"\t"进行重复操作,只进行了一次 public static void printDir(File file,int n) { File[] subFiles = file.listFiles(); for (File subFile : subFiles) { for(int i=0; i<=n; i++) { System.out.print("\t"); } System.out.println(subFile.getName()); if(subFile.isDirectory()) { printDir(subFile,n+1); } } } }