File类、递归
一、File类
1、概述
-
java.io.File类:是文件和目录(文件夹)路径名的抽象表示,主要用于文件和目录的创建、删除和查找等操作。
-
File是一个与操作系统无关的类,任何操作系统都可以使用这个类中的方法。
记住三个单词:
file:文件 directory:文件夹/目录 path:路径
2、Field
File类的静态成员变量:
- public static final String pathSeparator 与系统有关的路径分隔符;为了方便,它被表示为一个字符串
- public static final char pathSeparatorChar 与系统有关的路径分隔符
注意:两者是一样的
public static final String pathSeparator = "" + pathSeparatorChar;
- public static final String separator 与系统有关的默认名称分隔符;为了方便,它被表示为一个字符串
- public static final char separatorChar 与系统有关的默认名称分隔符
注意:两者是一样的
public static final String separator = "" + separatorChar;
import java.io.File;
public class Demo1File{
public static void main(String[] args){
/*
注意:操作路径时,路径不能写死。(因为各个OS所使用的分隔符不同)
C:\develop\a\a.txt windows
C:/develop/a/a.txt linux
"C:"+File.separator+"develop"+File.separator+"a"+File.separator+"a.txt"
*/
String pathSeparator = File.pathSeparator;
System.out.println(pathSeparator); //; 路径分隔符。windows:分号; linux:冒号:
String separator = File.separator;
System.out.println(separator); //\ 文件名称分隔符。windows:反斜杠\ linux:正斜杠/
}
}
3、路径
绝对路径:是一个完整的路径,以盘符(c:,d:)开始的路径。
C:\Users\Administrator\Desktop\Markdown study
D:\Course\JavaSE\基础语法\src\day08\file\demo1\File
相对路径:是一个简化的路径
相对指的是相对于当前项目的根目录;如果使用当前项目的根目录,路径可以简化书写。
D:\Course\JavaSE\基础语法\src\a.txt --> 简化为 a.txt(可以省略项目的根目录)
注意:
- 路径不区分大小写
- 路径中的文件名称分隔符windows使用反斜杠,而在java中反斜杠是转义字符,两个反斜杠才代表一个普通的反斜杠。
4、Constructor
- public File(String pathname); 通过将给定的路径名字符串转换为抽象路径名来创建一个新File实例
import java.io.File;
public class Demo2File{
public static void main(String[] args){
/*
public File(String pathname); 通过将给定的路径名字符串转换为抽象路径名来创建一个新File实例
参数:
String pathname:路径名字符串
路径可以是以文件结尾,也可以是以文件夹结尾
路径可以是相对路径,也可以是绝对路径
路径可以是存在,也可以是不存在
创建File对象,只是把字符串路径封装为File对象,不考虑路径的真假情况
*/
//绝对路径 以文件结尾 且不存在
File f1 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study\\a.txt");
//C:\Users\Administrator\Desktop\Markdown study\a.txt
System.out.println(f1); //重写了Object类的toString()
//绝对路径 以文件夹结尾 存在
File f2 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study");
System.out.println(f2); //C:\Users\Administrator\Desktop\Markdown study
//相对路径
File f3 = new File("b.txt");
System.out.println(f3); //b.txt
}
}
- public File(String parent,String child); 根据父路径字符串和子路径字符串创建一个新File实例
import java.io.File;
public class Demo3File{
public static void main(String[] args){
/*
public File(String parent,String child); 根据父路径字符串和子路径字符串创建一个新File实例
参数:把路径分成了两部分
String parent:父路径
String child:子路径
好处:
父路径和子路径可以单独书写,使用起来非常灵活;父路径和子路径都可以变化。
*/
show02("c:\\","a.txt"); //c:\a.txt
show02("d:\\","a.txt"); //d:\a.txt
}
public static void show02(String parent,String child) {
File file = new File(parent,child);
System.out.println(file);
}
}
- public FIle(File parent,String child); 根据 parent 抽象路径名和 child 路径名字符串创建一个新File实例
import java.io.File;
public class Demo4File{
public static void main(String[] args){
/*
public File(File parent,String child); 根据父抽象路径名和子路径名字符串创建一个新File实例
参数:把路径分成了两部分
String parent:父路径
String child:子路径
好处:
父路径和子路径可以单独书写,使用起来非常灵活;父路径和子路径都可以变化。
父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象。
*/
show03();
}
public static void show03(){
File parent = new File("d:\\");
File file = new File(parent,"hello.java");
System.out.println(file); //d:\hello.java
}
}
5、常用方法
5.1 获取功能的方法
- public String getAbsolutePath(); 返回此File的绝对路径名字符串
import java.io.File;
public class Demo5File{
public static void main(String[] args){
/*
public String getAbsolutePath(); 返回此File的绝对路径名字符串
获取的构造方法中传递的路径
无论路径是绝对的还是相对的,getAbsolutePath方法返回的都是绝对路径
*/
File f1 = new File("D:\\Course\\JavaSE\\基础语法\\src\\Day08\\a.txt");
String absolutePath1 = f1.getAbsolutePath();
System.out.println(absolutePath1); //D:\Course\JavaSE\基础语法\src\Day08\a.txt
File f2 = new File("a.txt");
String absolutePath2 = f2.getAbsolutePath();
System.out.println(absolutePath2); //D:\Course\JavaSE\基础语法\src\a.txt
}
}
- public String getPath(); 将此File转换为路径名字符串
import java.io.File;
public class Demo6File{
public static void main(String[] args){
/*
public String getPath(); 将此File转换为路径名字符串
获取的构造方法中传递的路径
传递的是绝对路径就返回绝对路径,传递的相对路径就返回相对路径。
File类中重写的toString()调用的就是getPath()。
源码:
public String toString() {
return getPath();
}
*/
File f1 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study");
File f2 = new File("b.txt");
String path1 = f1.getPath();
String path2 = f2.getPath();
System.out.println(path1); //C:\Users\Administrator\Desktop\Markdown study
System.out.println(path2); //b.txt
System.out.println(f1); //C:\Users\Administrator\Desktop\Markdown study
System.out.println(f1.toString()); //C:\Users\Administrator\Desktop\Markdown study
}
}
- public String getName(); 返回由此File表示的文件/目录的名称
import java.io.File;
public class Demo7File{
public static void main(String[] args){
/*
public String getName(); 返回由此File表示的文件/目录的名称
获取的就是构造方法传递路径的结尾部分(文件/文件夹)
*/
File f1 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study\\a.txt");
String name1 = f1.getName();
System.out.println(name1); //a.txt 获取的结尾部分是文件
File f2 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study");
String name2 = f2.getName();
System.out.println(name2); //Markdown study 获取的结尾部分是文件夹
}
}
- public long length(); 返回由此File表示的文件的大小
import java.io.File;
public class Demo8File{
public static void main(String[] args){
/*
public long length(); 返回由此File表示的文件的大小
获取的是构造方法指定的文件的大小,以字节为单位。
注意:
1.文件夹是没有大小概念的,不能获取文件夹的大小
2.如果构造方法中给出的路径不存在,那么length方法返回0
*/
File f1 = new File("C:\\Users\\Administrator\\Desktop\\a\\1.jpg");
long l1 = f1.length();
System.out.println(l1); //388260字节
File f2 = new File("C:\\Users\\Administrator\\Desktop\\a\\2.jpg");
System.out.println(f2.length()); //0
File f3 = new File("C:\\Users\\Administrator\\Desktop\\a");
System.out.println(f3.length()); //0 文件夹是没有大小概念的
}
}
5.2 判断功能的方法
- public boolean exists(); 判断此File表示的文件/目录是否实际存在
import java.io.File;
public class Demo9File{
public static void main(String[] args){
/*
public boolean exists(); 判断此File表示的文件/目录是否实际存在
用于判断构造方法中的路径是否存在
存在:true
不存在:false
*/
File f1 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study");
System.out.println(f1.exists()); //true
File f2 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study\\a.txt");
System.out.println(f2.exists()); //false
File f3 = new File("day03");
System.out.println(f3.exists()); //true
File f4 = new File("dayday");
System.out.println(f4.exists()); //false
}
}
- public boolean isDirectory(); 判断此File表示的是否为目录
- public boolean isFile(); 判断此File表示的是否为文件
import java.io.File;
public class Demo10File{
public static void main(String[] args){
/*
public boolean isDirectory(); 判断此File表示的是否为目录
用于判断构造方法中给定的路径是否以文件夹结尾
是:true
否:false
public boolean isFile(); 判断此File表示的是否为文件
用于判断构造方法中给定的路径是否以文件结尾
是:true
否:false
注意:
电脑的硬盘只有文件和文件夹,两个方法是互斥
这两个方法使用前提:路径必须是存在的,否则都返回false
*/
File f1 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study\\t.txt");
System.out.println(f1.isDirectory()); //false 文件不存在
System.out.println(f1.isFile()); //false 文件不存在
File f2 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study");
//加个判断,不存在就没有必要获取
if(f2.exists()){
System.out.println(f2.isDirectory()); //true 存在 以文件夹结尾
System.out.println(f2.isFile()); //false 存在 不是以文件结尾
}
File f3 = new File("C:\\Users\\Administrator\\Desktop\\Markdown study\\Day01.md");
if(f3.exists()){
System.out.println(f3.isDirectory()); //false 存在 不是以文件结尾
System.out.println(f3.isFile()); //true 存在 以文件结尾
}
}
}
5.3 创建、删除功能的方法
- public boolean creatNewFile(); 当且仅当具有该名称的文件不存在时,创建一个新的文件
import java.io.File;
public class Demo11File{
public static void main(String[] args){
/*
public boolean createNewFile(); 当且仅当具有该名称的文件不存在时,创建一个新的文件
创建文件的路径和名称在构造方法中给出(构造方法的参数)
返回值:布尔值
true:文件不存在,创建文件,返回true
false:文件存在,不会创建,返回false
注意:
1.此方法只能创建文件,不能创建文件夹
2.创建文件的路径必须存在,否则会抛出异常。
*/
//绝对路径:
File f1 = new File("C:\\Users\\Administrator\\Desktop\\a\\xzw.txt");
boolean b1 = f1.createNewFile();
System.out.println("b1: " + b1); //true
//相对路径:相对于当前项目所在的根目录
File f2 = new File("lyq.txt");
boolean b2 = f2.createNewFile();
System.out.println("b2: " + b2);
File f3 = new File("C:\\Desktop\\lss\\xzw\\lyq.txt");
boolean b3 = f3.createNewFile();
System.out.println(b3); //路径不存在 抛出IOException!
}
}
- public boolean delete(); 删除由此File表示的文件或目录
- public boolean mkdir(); 创建单级文件夹
- public boolean mkdirs(); 既可以创建单级文件夹,也可以创建多级文件夹
/*
public boolean mkdir(); 创建单级文件夹
public boolean mkdirs(); 既可以创建单级文件夹,也可以创建多级文件夹
创建文件的路径和名称在构造方法中给出(构造方法的参数)
返回值:布尔值
true:文件夹不存在,创建文件夹,返回true
false:文件夹存在,不会创建,返回false;构造方法中给出的文件夹路径不存在,也返回false
注意:
此方法只能创建文件夹,不能创建文件
public boolean delete(); 删除由此File表示的文件或目录
此方法,可以删除构造方法路径中给出的文件/文件夹
返回值:布尔值
true:文件/文件夹删除成功,返回true
false:文件夹中有内容,不会删除返回false;构造方法中路径不存在,也返回false
注意:
delete方法是直接在硬盘删除文件/文件夹,不走回收站,删除要谨慎!
*/
5.4 File类遍历(文件夹)目录功能
- public String[ ] list(); 返回一个String数组,表示该File目录中的所有子文件或目录
import java.io.File;
public class Demo12File{
public static void main(String[] args){
/*
public String[] list(); 返回一个String数组,表示该File目录中的所有子文件或目录
遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把获取到的多个名称
存储到一个String类型的数组中。
能够获取到隐藏的文件/文件夹。
*/
//NullPointerException 文件不存在
//File f1 = new File("D:\\Course\\JavaSE\\基础语法\\src\\Day0\\file");
//NullPointerException 给出的路径不是一个目录
//File f1 = new File("D:\\Course\\JavaSE\\基础语法\\src\\基础语法.iml");
File f1 = new File("D:\\Course\\JavaSE\\基础语法\\src\\Day08\\file");
String[] arr1 = f1.list();
for (String s : arr1) {
System.out.println(s);
}
}
}
- public File[ ] listFiles(); 返回一个File数组,表示该File目录中的所有子文件或目录
import java.io.File;
public class Demo13File{
public static void main(String[] args){
/*
public File[] listFiles(); 返回一个File数组,表示该File目录中的所有子文件或目录
遍历构造方法中给出的目录,会获取目录中所有文件/文件夹的名称,把文件/文件夹封装为File对象,
将多个File对象存储到数组中。
*/
File f1 = new File("D:\\Course\\JavaSE\\基础语法\\src\\Day08\\file");
File[] arr = f1.listFiles();
for(File f : arr){
System.out.println(f);
}
}
}
注意: list和listFiles方法遍历的是构造方法中给出的目录 如果构造方法中给出的目录的路径不存在,会抛出空指针异常! 如果构造方法给出的路径不是一个目录,也会抛出空指针异常!
二、递归
1、概述
- 指在当前方法内调用自己的这种现象。(方法自己调用自己)
2、分类
- 直接递归:方法自身调用自己。
- 间接递归:A方法调用B方法,B方法调用C方法,C方法调用A方法。
注意事项:
a. 递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
b. 在递归中虽然有限定条件,但是递归次数不能太多,否则也会发生栈内存溢出。
c. 构造方法,禁止递归。
构造方法是创建对象使用的,一直递归会导致内存中有无数多个对象,直接编译报错。
使用递归的前提:
当调用方法的时候,方法的主体不变,每次调用方法的参数不同,可以使用递归。
3、案例分析
3.1 计算1~n的和
/*
利用递归:计算1~n的和。 (用for循环更好!)
*/
public class Demo1Recursion {
public static void main(String[] args) {
System.out.println(sum(100));
}
public static int sum(int n){
if(n == 1){
return 1;
}
return n + sum(n-1);
}
}

3.2 计算n!
/*
利用递归:计算n的阶乘。
*/
public class Demo2Recursion {
public static void main(String[] args) {
int result = f(5);
System.out.println(result);
}
public static int f(int n){
if(n == 1){
return 1;
}
return n * f(n - 1);
}
}
3.3 用递归打印多级目录
import java.io.File;
/*
递归打印多级目录:
C:\Users\Administrator\Desktop\abc
a文件夹:
a.txt
1.jpg
b文件夹:
b.txt
2.jpg
lyq.java文件
xzw.txt文件
*/
public class Demo3Recursion {
public static void main(String[] args) {
File file = new File("C:\\Users\\Administrator\\Desktop\\abc");
getAllFile(file);
}
//定义一个遍历文件夹的方法
public static void getAllFile(File dir) {
System.out.println(dir.getName()); //打印遍历的目录名称
File[] files = dir.listFiles();
for (File f : files) {
//对遍历的对象进行判断,判断是否为文件夹
if (f.isDirectory()) {
//f是一个文件夹,则继续遍历这个文件夹
//发现getAllFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
} else {
//是一个文件,直接打印即可
System.out.println(f);
}
}
}
}
3.4 用递归进行文件搜索
import java.io.File;
/*
文件搜索:搜索C:\Users\Administrator\Desktop\abc目录中以.java结尾的文件:
abc文件夹包含:
a文件夹:
a.txt
1.jpg
b文件夹:
b.txt
2.jpg
lyq.java文件
xzw.txt文件
*/
public class Demo5Recursion {
public static void main(String[] args) {
File file = new File("C:\\Users\\Administrator\\Desktop\\abc");
getAllFile(file);
}
public static void getAllFile(File dir) {
File[] files = dir.listFiles();
for (File f : files) {
//对遍历的对象进行判断,判断是否为文件夹
if (f.isDirectory()) {
//f是一个文件夹,则继续遍历这个文件夹
//发现getAllFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
} else {
//是一个文件,直接打印即可
/*
C:\Users\Administrator\Desktop\abc\lyq.java
只要.java结尾的文件
1.把File对象f,转为字符串对象
*/
/*
//String name = f.getName(); //lyq.java
//String path = f.getPath();
//C:\Users\Administrator\Desktop\abc\lyq.java
String s = f.toString(); //C:\Users\Administrator\Desktop\abc\lyq.java
//把字符串转换为小写
s = s.toLowerCase();
//2.调用String类中的方法endsWith判断字符串是否以.java结尾
boolean b = s.endsWith(".java");
//3.如果是以.java结尾的,则输出
if(b){
System.out.println(f);
}
*/
//链式编程:简化代码
if(f.toString().toLowerCase().endsWith(".java")){
System.out.println(f);
}
}
}
}
}
4、FileFilter文件过滤器
import java.io.File;
import java.io.FileFilter;
/*
需求:
遍历C:\Users\Administrator\Desktop\abc文件夹,及abc文件夹的子文件夹
只要以.java结尾的文件:
C:\Users\Administrator\Desktop\abc
C:\Users\Administrator\Desktop\abc\lyq.java
C:\Users\Administrator\Desktop\abc\xzw.txt
C:\Users\Administrator\Desktop\abc\a
C:\Users\Administrator\Desktop\abc\a\1.jpg
C:\Users\Administrator\Desktop\abc\a\a.JAVA
C:\Users\Administrator\Desktop\abc\b
C:\Users\Administrator\Desktop\abc\b\b.java
C:\Users\Administrator\Desktop\abc\b\b.txt
可以使用过滤器来实现:
在File类中有两个和listFiles重载的方法,方法的参数传递的就是过滤器:
File[] listFiles(FileFilter filter)
java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器
作用:用来过滤文件(File对象)
包含抽象方法:用来过滤文件的方法
boolean accept(File pathname) 测试指定抽象路径名是否应该包含在某个路径名列表中
参数:
File pathname:使用listFiles方法遍历目录,得到的每一个文件对象。
File[] listFiles(FilenameFilter filter)
java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名。
作用:用来过滤文件名称
包含抽象方法:用来过滤文件的方法
boolean accept(File dir,String name) 测定指定文件是否应该包含在某一文件列表中
参数:
File dir:构造方法中传递的被遍历的目录
String name:使用listFiles方法遍历目录,获取的每一个文件/文件夹的名称
注意:
两个过滤器接口是没有实现类的,需要我们自己写实现类,重写过滤的方法accept,在方法中定义过滤的规则。
*/
public class Demo1Filter {
public static void main(String[] args) {
File file = new File("C:\\Users\\Administrator\\Desktop\\abc");
getAllFile(file);
}
//定义一个方法:参数传递File类型的目录,方法中对目录进行遍历
public static void getAllFile(File dir) {
File[] files = dir.listFiles(new FileFilterImpl(
/*
创建过滤器FileFilter的实现类(匿名内部类)
重写过滤方法accept,定义过滤规则。
*/
@Override
public boolean accept(File pathname) {
/*
过滤的规则:
在accept方法中,判断File对象是否以.java结尾
如果是,返回true
否则,返回false
*/
//如果pathname是一个文件夹,返回true,继续遍历这个文件夹
if(pathname.isDirectory()){
return true;
}
return pathname.getName().toLowerCase().endsWith(".java");
}));
//传递过滤器对象
for (File f : files) {
//对遍历的对象进行判断,判断是否为文件夹
if (f.isDirectory()) {
//f是一个文件夹,则继续遍历这个文件夹
//发现getAllFile方法就是传递文件夹,遍历文件夹的方法
//所以直接调用getAllFile方法即可:递归(自己调用自己)
getAllFile(f);
} else {
//是一个文件,直接打印即可
System.out.println(f);
}
}
}
}

浙公网安备 33010602011771号