1.3 创建和删除方法
刚才有同学问老师,我们不能不用Java代码创建一个文件或者文件夹呀?答案是有的,不光可以创建还可以删除。

**注意:**delete方法默认只能删除文件和空文件夹,删除后的文件不会进入回收站。
java
/**
* 目标:掌握File创建和删除文件相关的方法。
*/
public class FileTest3 {
public static void main(String[] args) throws Exception {
// 创建一个新文件(文件内容为空),创建成功返回true,反之。
File f1 = new File("D:\\resource\\abcd.txt");
System.out.println(f1.createNewFile());
// 用于创建文件夹,注意:只能创建一级文件夹
File f2 = new File("D:\\resource\\aaa");
System.out.println(f2.mkdir());
// 用于创建文件夹,注意:可以创建多级文件夹
File f3 = new File("D:\\resource\\bbb\\ccc\\ddd");
System.out.println(f3.mkdirs());
System.out.println("-------------");
// 删除文件,或者空文件,注意:不能删除非空文件夹。
System.out.println(f1.delete());
System.out.println(f2.delete());
File f4 = new File("D:\\resource\\");
System.out.println(f4.delete());
}
}
java
需要注意的是:
```java
1.mkdir(): 只能创建单级文件夹
2.mkdirs(): 才能创建多级文件夹
3.delete(): 文件可以直接删除,但是文件夹只能删除空的文件夹,文件夹有内容删除不了。
```
```java
1. 创建多级目录使用哪个方法?
public boolean mkdirs()
2. 删除文件需要注意什么?
可以删除文件、空文件夹。
默认不能删除非空文件夹。
```
1.4 遍历文件夹方法
有人说,想获取到一个文件夹中的内容,有没有方法呀?也是有的,下面我们就学习两个这样的方法。

java
/**
* 目标:掌握File提供的遍历文件夹的方法。
*/
public class FileTest4 {
public static void main(String[] args) throws Exception {
// 获取当前目录下所有的"一级文件名称"到一个字符串数组中去返回
File f1 = new File("E:\\胜雅教育\\Java课程\\01.JavaSE\\基础阶段");
String[] names = f1.list();
for (String name : names) {
System.out.println(name);
}
System.out.println("----------------------------------");
File[] files = f1.listFiles();
for (File file : files) {
// 获取文件的绝对路径
System.out.println(file.getAbsolutePath());
}
System.out.println("----------------------------------");
File f = new File("D:\\resource\\aaa");
File[] files1 = f.listFiles();
System.out.println(Arrays.toString(files1));
}
}
这里需要注意几个问题
1. 当主调是文件,或者路径不存在时,返回null
2. 当主调是空文件夹时,返回一个长度为0的数组
3. 当主调是一个有内容的文件夹时,将里面所有一级文件和文件夹的路径放在File数组中返回
4. 当主调是一个文件夹,且里面有隐藏文件时,将里面所有文件和文件夹的路径放在File数组中返回,包含隐藏文件
5. 当主调是一个文件夹,但是没有权限访问该文件夹时,返回null
如何遍历文件夹下的文件对象,使用哪个API,有什么特点?
public File[] listFiles()(常用)。
只能遍历当前文件夹对象下的一级文件对象。
关于遍历文件夹的基本操作就学习完了。 但是有同学如果想要获取文件夹中子文件夹的内容,那目前还做不到。但是学习下面的递归知识就很容易做到了。
二、递归
各位同学,为了获取文件夹中子文件夹的内容,我们就需要学习递归这个知识点。但是递归是什么意思,我们需要单独讲一下。学习完递归是什么,以及递归的执行流程之后,我们再回过头来用递归来找文件夹中子文件夹的内容。
2.1 递归算法引入
-
什么是递归?
从形式上说:方法调用自身的形式称为方法递归( recursion)。
-
递归的形式:
直接递归:方法自己调用自己。
间接递归:方法调用其他方法,其他方法又回调方法自己。
使用方法递归时需要注意的问题:
递归如果没有控制好终止,会出现递归死循环,导致栈内存溢出错误。
如下面的代码。
java
/**
* 目标:认识一下递归的形式。
*/
public class RecursionTest1 {
public static void main(String[] args) {
test1();
}
// 直接方法递归
private static void test1() {
System.out.println("---------test1---------");
test1(); // 直接递归:方法自己调用自己。
}
// 间接方法递归 (开发中很少使用)
public static void test2(){
System.out.println("---test2---");
test3();
}
public static void test3(){
test2(); // 间接递归
}
如果直接执行上面的代码,会进入死循环,最终导致栈内存溢出 
2.2 递归算法的执行流程
为了弄清楚递归的执行流程,接下来我们通过一个案例来学习一下。
案例需求:计算n的阶乘,比如5的阶乘 = 1 * 2 * 3 * 4 * 5 ; 6 的阶乘 = 1 * 2 * 3 * 4 * 5 * 6
分析需求用递归该怎么做
n的阶乘: 公式计算: 1*2*3*..*(n-1)*n 等价与 f(n) = f(n-1)*n
假设f(n)表示n的阶乘,那么我们可以推导出下面的式子
f(5) = 5*4*3*2*1
f(5) = f(4)*5
f(4) = f(3)*4
f(3) = f(2)*3
f(2) = f(1)*2
f(1) = 1
总结规律:
除了f(1) = 1; 出口
其他的f(n) = f(n-1)*n
我们可以把f(n)当做一个方法,那么方法的写法如下
java
/**
* 目标:掌握递归的应用,执行流程和算法思想。
*/
public class RecursionTest2 {
public static void main(String[] args) {
int result = f(5);
System.out.println("5的阶乘是:" + result);
}
//求n个数的阶乘
public static int f(int n){
// 终结点
if(n == 1){
return 1;
}else {
return f(n - 1) * n;
}
}
}
2.3 递归文件搜索
学习完递归算法执行流程后,最后我们回过头来。再来看一下,如果使用递归来遍历文件夹。
案例需求:在D:\\判断下搜索TIM.exe这个文件,然后直接输出。 绝对路径
分析:
1.先调用文件夹的listFiles方法,获取文件夹的一级内容,得到一个数组
2.然后再遍历数组,获取数组中的File对象(文件/文件夹)
3.因为File对象可能是文件也可能是文件夹,所以接下来就需要判断
判断File对象如果是文件,就获取文件名,如果文件名是`TIM.exe`则打印,否则不打印
判断File对象如果是文件夹,就递归执行1,2,3步骤
所以:把1,2,3步骤写成方法,递归调用即可。
java
/**
* 目标:掌握文件搜索的实现。
*/
public class RecursionTest3 {
public static void main(String[] args) throws Exception {
searchFile(new File("D:/") , "TIM.exe");
}
/**
* 去目录下搜索某个文件
* @param dir 目录
* @param fileName 要搜索的文件名称
*/
private static void searchFile(File dir, String fileName) throws Exception {
// 1. 把非法的情况都拦截住
if (dir == null || !dir.exists() || dir.isFile()){
return; // 代表无法搜索
}
/**
* 2. dir不是null, 存在, 一定是目录对象
* 获取当前目录下的全部一级文件对象
*/
File[] files = dir.listFiles();
// 3. 判断当前目录下是否存在一级文件对象, 以及是否存在可以拿到一级文件对象
if (files != null && files.length > 0){
// 4. 遍历全部一级文件对象
for (File file : files) {
// 5. 判断当前file是文件, 还是文件夹
if (file.isFile()){ // 是文件
// 是文件, 判断这个文件名是否是我们要找的文件名
if (file.getName().contains(fileName)){
// 找到了 打印当前文件的绝对路径
System.out.println("找到了: " + file.getAbsolutePath());
// 运行当前文件
Runtime runtime = Runtime.getRuntime();
runtime.exec(file.getAbsolutePath()); // 执行方法
}
}else {
// 是文件夹, 继续重复这个过程(递归继续找)
searchFile(file, fileName);
}
}
}
}
}