25--File类和递归
1、File类
java.io.File 类是文件和目录路径名的抽象表示,主要用于文件和目录的创建、查找和删除等操作。
1.1 File概述
File类及File相关的的各种流,都定义在java.io包下。
一个File对象代表硬盘或网络中可能存在的一个文件或者文件目录(俗称文件夹),与平台无关。
File 能新建、删除、重命名文件和目录,但 File 不能访问文件内容本身。如果需要访问文件内容本身,则需要使用输入/输出流。
- File对象可以作为参数传递给流的构造器。
想要在Java程序中表示一个真实存在的文件或目录,那么必须有一个File对象,但是Java程序中的一个File对象,可能没有一个真实存在的文件或目录。
1.2 File类构造方法
方法名 | 说明 |
public File(String pathname) | 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。 |
public File(String parent, String child) | 从父路径名字符串和子路径名字符串创建新的 File实例。 |
public File(File parent, String child) | 从父抽象路径名和子路径名字符串创建新的 File实例。 |
关于路径:
绝对路径:从盘符开始的路径,这是一个完整的路径。
相对路径:相对于项目目录的路径,这是一个便捷的路径,开发中经常使用。
- IDEA中,main中的文件的相对路径,是相对于"当前工程"
- IDEA中,单元测试方法中的文件的相对路径,是相对于"当前module"
代码演示
package com.suyv.file;
import org.junit.Test;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 13:59
*@Description: File类的构造方法
*/
public class FileDemo01 {
// public File(String pathname)
// 通过将给定的路径名字符串转换为抽象路径名来创建新的 File实例。
@Test
public void Test01(){
// 使用相对路径创建File对象
File file1 = new File("aaa.txt");
// 获取文件绝对路径
System.out.println(file1.getAbsoluteFile()); // F:\Java\JavaSE\Day17\aaa.txt
// 使用绝对路径创建File对象
File file2 = new File("D:\\aaa.txt");
// 获取文件绝对路径
System.out.println(file2.getAbsoluteFile()); // D:\aaa.txt
}
// public File(String parent, String child)
// 从父路径名字符串和子路径名字符串创建新的 File实例。
@Test
public void Test02(){
String parent = "D:\\aaa";
File file1 = new File(parent,"a1.txt");
// 获取文件绝对路径
System.out.println(file1.getAbsoluteFile()); // D:\aaa\a1.txt
}
// public File(File parent, String child)
// 从父抽象路径名和子路径名字符串创建新的 File实例。
@Test
public void Test03(){
// 使用绝对路径创建File对象
File parent = new File("D:\\aaa");
File file1 = new File(parent,"a.txt");
// 获取文件绝对路径
System.out.println(file1.getAbsoluteFile()); // D:\aaa\a.txt
// 使用相对路径创建File对象
File file = new File("aaa");
File file2 = new File(file,"a.txt");
// 获取文件绝对路径
System.out.println(file2.getAbsoluteFile()); // F:\Java\JavaSE\Day17\aaa\a.txt
}
}
一个File对象代表硬盘中实际存在的一个文件或者目录。
无论该路径下是否存在文件或者目录,都不影响File对象的创建。
1.3 File类的常用方法
1.3.1 获取文件和目录基本信息
public String getName() :获取名称
public String getPath() :获取路径
public String getAbsolutePath():获取绝对路径
public File getAbsoluteFile():获取绝对路径表示的文件
public String getParent():获取上层文件目录路径。若无,返回null
public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
public long lastModified() :获取最后一次的修改时间,毫秒值
package com.suyv.file;
import org.junit.Test;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 14:29
*@Description: 获取文件和目录基本信息
*/
public class FileDemo02 {
// public String getName() :获取名称
// public String getPath() :获取路径
// public String getAbsolutePath():获取绝对路径
// public File getAbsoluteFile():获取绝对路径表示的文件
// public String getParent():获取上层文件目录路径。若无,返回null
// public long length() :获取文件长度(即:字节数)。不能获取目录的长度。
// public long lastModified() :获取最后一次的修改时间,毫秒值,时间戳
// 相对路径--文件
@Test
public void Test01(){
// 文件不存在
File file1 = new File("file/a1.txt");
System.out.println("文件名称:" + file1.getName()); // 文件名称:a1.txt
System.out.println("文件路径:" + file1.getPath()); // 文件路径:file\a1.txt
System.out.println("文件绝对路径:" + file1.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file\a1.txt
System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\a1.txt
System.out.println("上层路径:" + file1.getParent()); // 上层路径:file
System.out.println("文件长度:" + file1.length()); // 文件长度:0
System.out.println("最后修改时间:" + file1.lastModified()); // 最后修改时间:0
// 文件存在
File file2 = new File("file/t1.txt");
System.out.println("文件名称:" + file2.getName()); // 文件名称:t1.txt
System.out.println("文件路径:" + file2.getPath()); // 文件路径:file\t1.txt
System.out.println("文件绝对路径:" + file2.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file\t1.txt
System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\t1.txt
System.out.println("上层路径:" + file2.getParent()); // 上层路径:file
System.out.println("文件长度:" + file2.length()); // 文件长度:20(字节)
System.out.println("最后修改时间:" + file2.lastModified()); // 最后修改时间:1702967947990(时间戳)
}
// 绝对路径--文件
@Test
public void Test02(){
// 文件不存在
File file1 = new File("F:\\Java\\JavaSE\\Day17\\file\\a1.txt");
System.out.println("文件名称:" + file1.getName()); // 文件名称:a1.txt
System.out.println("文件路径:" + file1.getPath()); // 文件路径:F:\Java\JavaSE\Day17\file\a1.txt
System.out.println("文件绝对路径:" + file1.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file\a1.txt
System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\a1.txt
System.out.println("上层路径:" + file1.getParent()); // 上层路径:F:\Java\JavaSE\Day17\file
System.out.println("文件长度:" + file1.length()); // 文件长度:0
System.out.println("最后修改时间:" + file1.lastModified()); // 最后修改时间:0
// 文件存在
File file2 = new File("F:\\Java\\JavaSE\\Day17\\file\\t1.txt");
System.out.println("文件名称:" + file2.getName()); // 文件名称:t1.txt
System.out.println("文件路径:" + file2.getPath()); // 文件路径:F:\Java\JavaSE\Day17\file\t1.txt
System.out.println("文件绝对路径:" + file2.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file\t1.txt
System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file\t1.txt
System.out.println("上层路径:" + file2.getParent()); // 上层路径:F:\Java\JavaSE\Day17\file
System.out.println("文件长度:" + file2.length()); // 文件长度:20(字节)
System.out.println("最后修改时间:" + file2.lastModified()); // 最后修改时间:1702967947990(时间戳)
}
// 相对路径--目录
@Test
public void Test03(){
// 目录不存在
File file1 = new File("file1");
System.out.println("文件名称:" + file1.getName()); // 文件名称:file1
System.out.println("文件路径:" + file1.getPath()); // 文件路径:file1
System.out.println("文件绝对路径:" + file1.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file1
System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file1
System.out.println("上层路径:" + file1.getParent()); // 上层路径:null
System.out.println("文件长度:" + file1.length()); // 文件长度:0
System.out.println("最后修改时间:" + file1.lastModified()); // 最后修改时间:0
// 目录存在
File file2 = new File("file");
System.out.println("文件名称:" + file2.getName()); // 文件名称:file
System.out.println("文件路径:" + file2.getPath()); // 文件路径:file
System.out.println("文件绝对路径:" + file2.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file
System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file
System.out.println("上层路径:" + file2.getParent()); // 上层路径:null
System.out.println("文件长度:" + file2.length()); // 文件长度:0
System.out.println("最后修改时间:" + file2.lastModified()); // 最后修改时间:1702967947990(时间戳)
}
// 绝对路径--目录
@Test
public void Test04(){
// 目录不存在
File file1 = new File("F:\\Java\\JavaSE\\Day17\\file1");
System.out.println("文件名称:" + file1.getName()); // 文件名称:file1
System.out.println("文件路径:" + file1.getPath()); // 文件路径:F:\Java\JavaSE\Day17\file1
System.out.println("文件绝对路径:" + file1.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file1
System.out.println("文件绝对路径表示的文件:" + file1.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file1
System.out.println("上层路径:" + file1.getParent()); // 上层路径:F:\Java\JavaSE\Day17
System.out.println("文件长度:" + file1.length()); // 文件长度:0
System.out.println("最后修改时间:" + file1.lastModified()); // 最后修改时间:0
// 目录存在
File file2 = new File("F:\\Java\\JavaSE\\Day17\\file");
System.out.println("文件名称:" + file2.getName()); // 文件名称:file
System.out.println("文件路径:" + file2.getPath()); // 文件路径:F:\Java\JavaSE\Day17\file
System.out.println("文件绝对路径:" + file2.getAbsolutePath()); // 文件绝对路径:F:\Java\JavaSE\Day17\file
System.out.println("文件绝对路径表示的文件:" + file2.getAbsoluteFile()); // 文件绝对路径表示的文件:F:\Java\JavaSE\Day17\file
System.out.println("上层路径:" + file2.getParent()); // 上层路径:F:\Java\JavaSE\Day17
System.out.println("文件长度:" + file2.length()); // 文件长度:0
System.out.println("最后修改时间:" + file2.lastModified()); // 最后修改时间:1702967947990(时间戳)
}
}
1.3.2 列出目录的下一级
public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
package com.suyv.file;
import org.junit.Test;
import java.io.File;
import java.util.Arrays;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 14:49
*@Description: 列出目录的下一级
*/
public class FileDemo03 {
// public String[] list() :返回一个String数组,表示该File目录中的所有子文件或目录。
// public File[] listFiles() :返回一个File数组,表示该File目录中的所有的子文件或目录。
@Test
public void Test01(){
File file = new File("file");
String[] list = file.list();
System.out.println(Arrays.toString(list)); // [t1.txt]
}
@Test
public void Test02(){
File file = new File("file");
File[] files = file.listFiles();
System.out.println(files); // [Ljava.io.File;@4ee285c6
}
}
注意事项
调用listFiles方法的File对象,表示的必须是实际存在的目录,否则返回null,无法进行遍历。
1.3.3 File类的重命名功能
public boolean renameTo(File dest):把文件重命名为指定的文件路径。
package com.suyv.file;
import org.junit.Test;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 15:47
*@Description: File类的重命名功能
*/
public class FileDemo04 {
// public boolean renameTo(File dest):把文件重命名为指定的文件路径。
// 同目录时表示重命名
@Test
public void Test01() {
File file1 = new File("file\\abc.txt");
File file2 = new File("file\\hello.txt");
boolean renameSuccess = file1.renameTo(file2);
System.out.println(renameSuccess ? "重命名成功" : "重命名失败");
}
// file1.renameTo(file2):要想此方法执行完,返回true。
// 要求:file1必须存在,且file2必须不存在,且file2所在的文件目录需要存在。
// 不同目录时相当于剪切文件
@Test
public void Test02(){
File file1 = new File("file\\abc.txt");
File file2 = new File("hello.txt");
boolean renameSuccess = file1.renameTo(file2);
System.out.println(renameSuccess ? "重命名成功" : "重命名失败");
}
}
1.3.4 判断功能的方法
public boolean exists() :此File表示的文件或目录是否实际存在。
public boolean isDirectory() :此File表示的是否为目录。
public boolean isFile() :此File表示的是否为文件。
public boolean canRead() :判断是否可读
public boolean canWrite() :判断是否可写
public boolean isHidden() :判断是否隐藏
package com.suyv.file;
import org.junit.Test;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 16:38
*@Description: File类判断功能的方法
*/
public class FileDemo05 {
// public boolean exists() :此File表示的文件或目录是否实际存在。
// public boolean isDirectory() :此File表示的是否为目录。
// public boolean isFile() :此File表示的是否为文件。
// public boolean canRead() :判断是否可读
// public boolean canWrite() :判断是否可写
// public boolean isHidden() :判断是否隐藏
@Test
public void Test01(){
// 文件存在
File file1 = new File("file\\t1.txt");
// 文件不存在
File file2 = new File("file\\t2.txt");
// 目录存在
File file3 = new File("file\\test");
// 目录不存在
File file4 = new File("file\\test01");
// 隐藏文件
File file5 = new File("file\\hidden.txt");
// exists()
System.out.println(file1.exists()); // true
System.out.println(file2.exists()); // false
// isDirectory() 结果为true的条件是文件夹必须存在,结果为false的当前文件夹不存在或者不是文件夹
System.out.println(file1.isDirectory()); // false
System.out.println(file3.isDirectory()); // true
// isFile 结果为true的条件是文件必须存在,结果为false的当前文件夹不存在或者不是文件
System.out.println(file1.isFile()); // true
System.out.println(file3.isFile()); // false
// canRead()
System.out.println(file1.canRead()); // true
// canWrite()
System.out.println(file1.canWrite()); // true
// isHidden()
System.out.println(file1.isHidden()); // false
System.out.println(file5.isHidden()); // true
}
}
如果文件或目录不存在,那么exists()、isFile()和isDirectory()都是返回false
1.3.5 创建、删除功能
public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false。
public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。
public boolean delete() :删除文件或者文件夹
删除注意事项:① Java中的删除不走回收站。
② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。
package com.suyv.file;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 16:53
*@Description: 创建、删除功能
*/
public class FileDemo06 {
// public boolean createNewFile() :创建文件。若文件存在,则不创建,返回false。
// public boolean mkdir() :创建文件目录。如果此文件目录存在,就不创建了。如果此文件目录的上层目录不存在,也不创建。
// public boolean mkdirs() :创建文件目录。如果上层文件目录不存在,一并创建。
// public boolean delete() :删除文件或者文件夹删除注意事项:
// ① Java中的删除不走回收站。② 要删除一个文件目录,请注意该文件目录内不能包含文件或者文件目录。
// creatNewFile()创建文件时,必须保证该文件的父级目录必须存在
@Test
public void Test01() throws IOException {
File file = new File("file\\红楼梦.txt");
if (file.createNewFile()) {
System.out.println("创建文件成功");
} else {
System.out.println("创建文件失败");
}
}
// mkdir()创建文件夹时,如果父级目录不存在,则不创建该文件夹
@Test
public void Test02(){
File file = new File("file\\小说");
if (file.mkdir()) {
System.out.println("创建成功");
} else {
System.out.println("创建失败");
}
}
// mkdirs()创建文件夹时,如果父级目录不存在,则创建父级目录
@Test
public void Test03(){
File file = new File("file\\文学\\历史");
if (file.mkdirs()) {
System.out.println("创建成功");
} else {
System.out.println("创建失败");
}
}
// delete()如果目录中有内容则不能删除
@Test
public void Test04(){
File file = new File("file\\test\\t.txt");
if (file.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
File file1 = new File("file\\文学");
if (file1.delete()) {
System.out.println("删除成功");
} else {
System.out.println("删除失败");
}
}
}
2、递归
2.1 递归概述
2.1.1 什么是递归
指在当前方法直接或者间接调用自己的情况。
2.1.2 递归的分类
递归分为两种,直接递归 和 间接递归。
直接递归:称为方法自身调用自己。A方法调用B方法B方法调用A方法..
间接递归:可以A方法调用B方法,B方法调用C方法,C方法调用A方法。
2.1.3 递归的注意事项
递归一定要有条件限定,保证递归能够停止下来,否则会发生栈内存溢出。
在递归中虽然有限定条件,但是递归次数不能太多。否则也会发生栈内存溢出。
构造方法中禁止递归
2.2 递归案例
2.2.1 递归累加求和
需求
- 计算1 ~ n的和
分析
- num的累和 = num + (num-1)的累和,所以可以把累和的操作定义成一个方法,递归调用。
代码实现
package com.suyv.recursion;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:33
*@Description: 递归累加求和
*/
public class RecursionDemo {
public static void main(String[] args) {
System.out.println(getSum(5));
}
public static int getSum(int num){
if (num == 1){
return 1;
}
int ge = getSum(num - 1);
return ge + num;
}
}
2.2.2 递归求阶乘
什么是阶乘
- 所有小于及等于该数的正整数的积。使用递归求5的阶乘5! = 5 * 4 * 3 * 2 * 1 5! = 5 * 4! 4! = 4 * 3! 3! = 3 * 2! 2! = 2 * 1! 1! = 1求n的阶乘 n * (n - 1)!
求N阶乘公式
- n! = n * (n-1) ... 3 * 2 * 1
分析
- 这与累和类似,只不过换成了乘法运算,学员可以自己练习,需要注意阶乘值符合int类型的范围。推理得出:n! = n * (n-1)!
代码实现
package com.suyv.recursion;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:44
*@Description: 递归求阶乘
*/
public class RecursionDemo02 {
public static void main(String[] args) {
System.out.println(getSum(5));
}
public static int getSum(int num){
if (num == 1){
return 1;
}
int ge = getSum(num - 1);
return ge * num;
}
}
3、综合案例
3.1 打印多级目录
分析
- 多级目录的打印,就是当目录的嵌套。遍历之前,无从知道到底有多少级目录,所以我们还是要使用递归实现。
代码实现
package com.work;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 18:23
*@Description: 使用递归
*/
public class Demo03 {
public static void main(String[] args) {
// 定义一个文件夹,在该文件夹中有三个子文件和两个子文件夹,再每一个子文件夹中又各有几个子文件。
// 要求: 打印文件夹下的所有的子文件名和文件完整路径(包含子文件下的文件哦!)
// 创建文件夹对象
File file = new File("D:\\test");
String path = file.getPath();
printFile(path);
}
// 使用递归方法
public static void printFile(String path){
File file = new File(path);
// 判断文件是否存在
if (file.exists()) {
// 取出文件中的目录和文件
File[] fileArray = file.listFiles();
for (File f : fileArray) {
// 判断是否为目录
if (f.isDirectory()) {
printFile(f.getPath());
} else {
System.out.println(f.getName() + "的绝对路径为:" + f.getAbsolutePath());
}
}
}
}
}
3.2 文件搜索
需求
- 搜索D:\aaa 目录中的.java 文件。
需求分析
- 目录搜索,无法判断多少级目录,所以使用递归,遍历所有目录。遍历目录时,获取的子文件,通过文件名称的后缀,判断是否符合条件。
代码实现
package com.suyv.recursion;
import java.io.File;
/**
*@Author: 憨憨浩浩
*@CreateTime: 2023-12-19 19:46
*@Description: TODO
*/
public class RecursionDemo03 {
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);
}
}
}
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!