JAVA Basics-Chapter 17 File Class, Recursion

main content

File class
recursion

teaching objectives

Able to tell how the File object was created,
Able to tell the name of the method by which the File class gets the name
Able to tell the name of the method by which the File class gets the absolute path
Able to say the name of the method for the File class to get the file size
Able to say the File class to judge whether it is a file Method name
Can tell the method name of the File class to determine whether it is a folder
Can distinguish relative and absolute paths
Can traverse folders
Can explain the meaning of
recursion Can use recursion to calculate the factorial of 5
Can tell the hidden danger of memory overflow using recursion the reason

Chapter One File Class

1.1 Overview

java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。

1.2 Construction method

public File(String pathname) :通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
public File(String parent, String child) :从父路径名字符串和子路径名字符串创建新的 File实例。
public File(File parent, String child) :从父抽象路径名和子路径名字符串创建新的 File实例。
构造举例,代码如下:

// file path name

String pathname = "D:\\aaa.txt";
File file1 = new File(pathname);
// 文件路径名
String pathname2 = "D:\\aaa\\bbb.txt";
File file2 = new File(pathname2);

Tips:

1. 一个File对象代表硬盘中实际存在的一个文件或者目录。
2. 无论该路径下是否存在文件或者目录,都不影响File对象的创建。

1.3 Common methods

How to get features

public String getAbsolutePath() :返回此File的绝对路径名字符串。
public String getPath() :将此File转换为路径名字符串。
public String getName() :返回由此File表示的文件或目录的名称。
public long length() :返回由此File表示的文件的长度。
方法演示,代码如下:

// Pass the parent path and sub path string

String parent = "d:\\aaa";
String child = "bbb.txt";
File file3 = new File(parent, child);
// 通过父级File对象和子路径字符串
File parentDir = new File("d:\\aaa");
String child = "bbb.txt";
File file4 = new File(parentDir, child);
public class FileGet {
public static void main(String[] args) {
File f = new File("d:/aaa/bbb.java");    
System.out.println("文件绝对路径:"+f.getAbsolutePath());
System.out.println("文件构造路径:"+f.getPath());
System.out.println("文件名称:"+f.getName());
System.out.println("文件长度:"+f.length()+"字节");
File f2 = new File("d:/aaa");    
System.out.println("目录绝对路径:"+f2.getAbsolutePath());
System.out.println("目录构造路径:"+f2.getPath());
System.out.println("目录名称:"+f2.getName());
System.out.println("目录长度:"+f2.length());
    }
}
输出结果:
文件绝对路径:d:\aaa\bbb.java
文件构造路径:d:\aaa\bbb.java
文件名称:bbb.java
文件长度: 636 字节
目录绝对路径:d:\aaa
目录构造路径:d:\aaa
目录名称:aaa
API中说明:length(),表示文件的长度。但是File对象表示目录,则返回值未指定。

Absolute path and relative path

Absolute path: the path starting from the drive letter, this is a complete path.

Relative path: Relative to the path of the project directory, this is a convenient path that is often used in development.

Method of judging function

public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。

Method demonstration, the code is as follows:

How to create delete function

Directory length: 4096

public class FilePath {
public static void main(String[] args) {
// D盘下的bbb.java文件
File f = new File("D:\\bbb.java");
System.out.println(f.getAbsolutePath());
// 项目下的bbb.java文件
File f2 = new File("bbb.java");
System.out.println(f2.getAbsolutePath());
    }
}
输出结果:
D:\bbb.java
D:\idea_project_test4\bbb.java
public class FileIs {
public static void main(String[] args) {
File f = new File("d:\\aaa\\bbb.java");
File f2 = new File("d:\\aaa");
// 判断是否存在
System.out.println("d:\\aaa\\bbb.java 是否存在:"+f.exists());
System.out.println("d:\\aaa 是否存在:"+f2.exists());
// 判断是文件还是目录
System.out.println("d:\\aaa 文件?:"+f2.isFile());
System.out.println("d:\\aaa 目录?:"+f2.isDirectory());
    }
}
输出结果:
d:\aaa\bbb.java 是否存在:true
d:\aaa 是否存在:true
d:\aaa 文件?:false
d:\aaa 目录?:true
public boolean createNewFile() :当且仅当具有该名称的文件尚不存在时,创建一个新的空文件。
public boolean delete() :删除由此File表示的文件或目录。
public boolean mkdir() :创建由此File表示的目录。
public boolean mkdirs() :创建由此File表示的目录,包括任何必需但不存在的父目录。

Method demonstration, the code is as follows:

API中说明:delete方法,如果此File表示目录,则目录必须为空才能删除。

1.4 Directory traversal

public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
public class FileCreateDelete {
public static void main(String[] args) throws IOException {
// 文件的创建
File f = new File("aaa.txt");
System.out.println("是否存在:"+f.exists()); // false
System.out.println("是否创建:"+f.createNewFile()); // true
System.out.println("是否存在:"+f.exists()); // true
// 目录的创建
File f2= new File("newDir");
System.out.println("是否存在:"+f2.exists());// false
System.out.println("是否创建:"+f2.mkdir()); // true
System.out.println("是否存在:"+f2.exists());// true
// 创建多级目录
File f3= new File("newDira\\newDirb");
System.out.println(f3.mkdir());// false
File f4= new File("newDira\\newDirb");
System.out.println(f4.mkdirs());// true
// 文件的删除
System.out.println(f.delete());// true
// 目录的删除
System.out.println(f2.delete());// true
System.out.println(f4.delete());// false
    }
}
public class FileFor {
public static void main(String[] args) {
File dir = new File("d:\\java_code");
//获取当前目录下的文件以及文件夹的名称。
String[] names = dir.list();
for(String name : names){
System.out.println(name);
}

Tips:

调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。

Chapter 2 Recursion

2.1 Overview

Recursion: Refers to the phenomenon of calling oneself within the current method.

Recursive classification:

There are two types of recursion, direct recursion and indirect recursion.

Direct recursion is called the method calling itself.

Indirect recursion can call A method B method, B method call C method, C method call A method.

Precautions:

Recursion must be conditionally limited to ensure that the recursion can stop, otherwise stack memory overflow will occur.

Although there are limited conditions in recursion, the number of recursion cannot be too many. Otherwise, stack memory overflow will occur.

Construction method, recursion is prohibited

}

//Get files and folder objects in the current directory, as long as you get the file object, you can get more information

File[] files = dir.listFiles();
for (File file : files) {
System.out.println(file);
        }
    }
}
public class Demo01DiGui {
public static void main(String[] args) {
// a();
b( 1 );
}
/*
* 3.构造方法,禁止递归
* 编译报错:构造方法是创建对象使用的,不能让对象一直创建下去
*/
public Demo01DiGui() {
//Demo01DiGui();
}

/*

* 2. Although there are limited conditions in recursion, the number of recursion cannot be too many. Otherwise, stack memory overflow will occur.

*

*  Exception in thread "main" java.lang.StackOverflowError
*/
private static void b(int i) {
System.out.println(i);
//添加一个递归结束的条件,i==5000的时候结束

2.2 Recursive cumulative sum

Calculate the sum of 1 ~ n

Analysis: the cumulative sum of num = the cumulative sum of num + (num-1), so the cumulative operation can be defined as a method, which is called recursively.

Implementation code:

//添加一个递归结束的条件,i==5000的时候结束
if(i== 5000 ){
return;//结束方法
}
b(++i);
}
/*
* 1.递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。 Exception in thread "main"
* java.lang.StackOverflowError
*/
private static void a() {
System.out.println("a方法");
a();
}
}
public class DiGuiDemo {
public static void main(String[] args) {
//计算1~num的和,使用递归完成
int num =  5 ;
// 调用求和的方法
int sum = getSum(num);
// 输出结果
System.out.println(sum);
}
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getSum(int num) {
/*
num为 1 时,方法返回1,
相当于是方法的出口,num总有是 1 的情况
*/
if(num ==  1 ){
return  1 ;
}
/*
num不为 1 时,方法返回 num +(num‐1)的累和
递归调用getSum方法
*/
return num + getSum(num‐ 1 );

Code execution diagram

Tips: Recursion must be conditionally limited to ensure that the recursion can be stopped, not too many times, otherwise stack memory overflow will occur.

2.3 Recursively find factorial

Factorial: The product of all positive integers less than or equal to this number.

Analysis: This is similar to tired sum, except that it is replaced by multiplication. Students can practice on their own. It is necessary to note that the factorial value conforms to the range of int type.

Code:

return num + getSum(num‐ 1 );
}
}
n的阶乘:n! = n * (n‐ 1 ) *...*  3  *  2  *  1 
推理得出:n! = n * (n‐1)!
public class DiGuiDemo {
//计算n的阶乘,使用递归完成
public static void main(String[] args) {
int n =  3 ;
// 调用求阶乘的方法
int value = getValue(n);
// 输出结果

2.4 Recursive printing of multi-level directories

Analysis: The printing of multi-level directories is the nesting of directories. Before traversing, there is no way to know how many levels of directories there are, so we still have to use recursive implementation

Now.

Code:

System.out.println("阶乘为:"+ value);
    }
/*
通过递归算法实现.
参数列表:int
返回值类型: int
*/
public static int getValue(int n) {
// 1的阶乘为 1
if (n ==  1 ) {
return  1 ;
        }
/*
n不为 1 时,方法返回 n! = n*(n‐1)!
递归调用getValue方法
*/
return n * getValue(n ‐  1 );
    }
}
public class DiGuiDemo2 {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
    }
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
/*
判断:
当是文件时,打印绝对路径.
当是目录时,继续调用打印目录的方法,形成递归调用.
*/
for (File file : files) {
// 判断
if (file.isFile()) {
// 是文件,输出文件绝对路径
System.out.println("文件名:"+ file.getAbsolutePath());
            } else {
// 是目录,输出目录绝对路径
System.out.println("目录:"+file.getAbsolutePath());
// 继续遍历,调用printDir,形成递归

Chapter 3 Comprehensive Case

3.1 File search

Search for the .java file in the D:\aaa directory.

analysis:

1. 目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录。
2. 遍历目录时,获取的子文件,通过文件名称,判断是否符合条件。

Code:

3.2 File filter optimization

java.io.FileFilter is an interface, a filter for File. The object of this interface can be passed to the listFiles(FileFilter) of the File class
as a parameter. There is only one method in the interface.

// 继续遍历,调用printDir,形成递归
printDir(file);
            }
        }
    }
}
public class DiGuiDemo3 {
public static void main(String[] args) {
// 创建File对象
File dir = new File("D:\\aaa");
// 调用打印目录方法
printDir(dir);
    }
public static void printDir(File dir) {
// 获取子文件和目录
File[] files = dir.listFiles();
// 循环打印
for (File file : files) {
if (file.isFile()) {
// 是文件,判断文件名并输出文件绝对路径
if (file.getName().endsWith(".java")) {
System.out.println("文件名:" + file.getAbsolutePath());
                }
            } else {
// 是目录,继续遍历,形成递归
printDir(file);
            }
        }
    }
}
boolean accept(File pathname) :测试pathname是否应该包含在当前File目录中,符合则返回true。

analysis:

1. 接口作为参数,需要传递子类对象,重写其中方法。我们选择匿名内部类方式,比较简单。
2. accept方法,参数为File,表示当前File下所有的子文件和子目录。保留住则返回true,过滤掉则返回
false。保留规则:
1. 要么是.java文件。
2. 要么是目录,用于继续遍历。
3. 通过过滤器的作用,listFiles(FileFilter)返回的数组元素中,子文件对象都是符合条件的,可以直接打
印。

Code:

3.3 Lambda optimization

Analysis: FileFilter is an interface with only one method, so it can be abbreviated with lambda expressions.

Lambda format:

Code:

public class DiGuiDemo4 {
public static void main(String[] args) {
File dir = new File("D:\\aaa");
printDir2(dir);
    }
public static void printDir2(File dir) {
// 匿名内部类方式,创建过滤器子类对象
File[] files = dir.listFiles(new FileFilter() {
@Override
public boolean accept(File pathname) {
return pathname.getName().endsWith(".java")||pathname.isDirectory();
            }
        });
// 循环打印
for (File file : files) {
if (file.isFile()) {
System.out.println("文件名:" + file.getAbsolutePath());
            } else {
printDir2(file);
            }
        }
    }
}      

()‐>{ }

public static void printDir3(File dir) {
// lambda的改写
File[] files = dir.listFiles(f ‐>{
return f.getName().endsWith(".java") || f.isDirectory();
});

// Loop printing
for (File file: files) { if (file.isFile()) { System.out.println("File name:" + file.getAbsolutePath()); } else { printDir3(file); } } }






Guess you like

Origin blog.csdn.net/weixin_43419256/article/details/108230731