本文纲要
File和IO概述File类的构造方法- 绝对路径与相对路径
File的创建功能File的删除方法File的判断与获取方法File的高级获取方法:listFiles- 项目代码结构
- 综合练习
练习1:在指定目录中创建文件
练习2:递归删除多级文件夹
练习3:统计文件夹中每种文件出现的次数
File和IO概述
在Java中,我们经常需要对硬盘上的文件进行读写操作,实现数据的永久化存储。例如:保存用户配置、导出报表、日志记录等。
回想一下,使用变量、数组或集合存储数据,当程序运行结束后所有数据都会丢失。而借助硬盘这一硬件,我们可以在程序退出后依然保留数据。在操作系统中,我们通常对硬盘进行读和写两种操作,但在读写之前,必须先知道文件在哪儿。
IO流:负责将数据从本地文件读取到内存,或者将内存中的数据写入本地文件,实现永久存储。
File类:用于描述要操作的文件或文件夹的路径,同时也能对文件/文件夹本身进行创建、删除等操作。
简言之:File 定位文件位置,IO 流负责读写数据。
File类的构造方法
java.io.File 类是文件和目录路径名的抽象表示。
它封装的对象可以是存在的路径,也可以是不存在的路径。学习一个类,先从构造方法开始。
File 提供了三种常用构造:
| 构造方法 | 说明 |
|---|---|
File(String pathname) | 将字符串路径转换为File对象 |
File(String parent, String child) | 拼接父路径和子路径创建File对象 |
File(File parent, String child) | 拼接父File对象与子路径创建File对象 |
为什么要把字符串表示的路径变成File对象?
因为 String 类本身没有操作文件的方法(如删除、创建等),而 File 类提供了丰富的方法。
因此我们需要将路径包装成File对象来调用这些方法
下面是三种构造方法的演示代码:
// FileDemo1.java
public class FileDemo1 {
public static void main(String[] args) {
method1();
method2();
method3();
}
// 1. File(String pathname)
private static void method1() {
String path = "C:\\wb\\a.txt";
File file = new File(path);
// 将字符串路径封装为File对象,以便使用File类的方法
System.out.println(file); // C:\wb\a.txt
}
// 2. File(String parent, String child) -- 路径拼接
private static void method2() {
String path1 = "C:\\wb";
String path2 = "a.txt";
File file = new File(path1, path2);
System.out.println(file); // C:\wb\a.txt
}
// 3. File(File parent, String child) -- 父File + 子路径
private static void method3() {
File file1 = new File("C:\\wb");
String path = "a.txt";
File file = new File(file1, path);
System.out.println(file); // C:\wb\a.txt
}
}
应用场景:
- 第一种构造:当一个完整路径字符串需要被操作时使用。
- 第二/三种构造:多用于路径拼接,例如已知目录和文件名进行组合。
绝对路径与相对路径
Java中的路径分为两类:
- 绝对路径:从盘符开始,位置固定不变。例如 D:\wb\a.txt。
- 相对路径:相对当前项目而言,没有盘符开头。例如 a.txt 表示当前项目根目录下的文件。
代码示例
// FileDemo2.java
public class FileDemo2 {
public static void main(String[] args) {
// 绝对路径:固定指向D盘下的文件
File file1 = new File("D:\\wb\\a.txt");
// 相对路径:当前项目根目录下的a.txt
File file2 = new File("a.txt");
// 相对路径:当前项目下指定模块中的a.txt
File file3 = new File("filemodule\\a.txt");
}
}
注:相对路径的参照物是“当前项目”。
如果要把文件放在模块内部,需要加上模块名。
File的创建功能
File类提供了三个创建方法:
| 方法 | 说明 |
|---|---|
boolean createNewFile() | 创建一个新文件,若已存在则返回false |
boolean mkdir() | 创建单级文件夹,不能创建多级 |
boolean mkdirs() | 创建多级文件夹(也可创建单级) |
注意点总结 (来自注释与实验):
createNewFile 不管调用者的名称是否有后缀,只能创建文件;若文件所在目录不存在,会抛出 IOException。
mkdir 只能创建单级文件夹;即使名称带后缀,也只能创建文件夹。
mkdirs 可以创建单级或多级文件夹;不管调用者有没有后缀,都只创建文件夹。
代码演示
// FileDemo3.java
public class FileDemo3 {
public static void main(String[] args) throws IOException {
method1(); // createNewFile
method2(); // mkdir
// 演示 mkdirs
File file = new File("C:\\wb\\aaa.txt");
boolean result = file.mkdirs();
System.out.println(result); // true
}
// createNewFile:只能创建文件
private static void method1() throws IOException {
// 假设C:\wb\aaa 不存在
File file1 = new File("C:\\wb\\aaa");
boolean result1 = file1.createNewFile();
System.out.println(result1);
// 即使名称为aaa,仍然创建的是一个无后缀的文件
}
// mkdir:只能创建单级文件夹
private static void method2() {
File file = new File("C:\\wb\\aaa.txt");
boolean result = file.mkdir();
System.out.println(result);
// 即使名称为aaa.txt,仍会创建名为"aaa.txt"的文件夹
}
}
补充:mkdirs 底层会先尝试调用 mkdir,如果创建单级失败再递归创建多级,因此开发中一般直接使用 mkdirs 即可。
File的删除方法
boolean delete() 用于删除文件或空文件夹。
注意点:
- 删除不走回收站,直接从硬盘移除,不可恢复。
- 如果删除的是文件,则直接删除。
- 如果删除的是文件夹,只能删除空文件夹。
- 若想删除有内容的文件夹,需先递归删除内部所有内容,再删除该文件夹自身。
代码演示
// FileDemo4.java
public class FileDemo4 {
public static void main(String[] args) {
method1(); // 删除文件
// 删除空文件夹示例
File file = new File("C:\\wb");
boolean result = file.delete();
System.out.println(result);
}
private static void method1() {
File file = new File("C:\\wb\\a.txt");
boolean result = file.delete();
System.out.println(result);
}
}
File的判断与获取方法
| 方法 | 说明 |
|---|---|
boolean isFile() | 判断是否为文件 |
boolean isDirectory() | 判断是否为文件夹 |
boolean exists() | 判断文件或文件夹是否存在 |
String getName() | 获取文件或文件夹名称(文件包含后缀) |
代码演示
// FileDemo5.java
public class FileDemo5 {
public static void main(String[] args) {
method1(); // isFile & isDirectory (文件)
method2(); // isFile & isDirectory (文件夹)
method3(); // exists
// getName 演示
File file = new File("a.txt");
System.out.println(file.getName()); // a.txt
File file1 = new File("C:\\wb");
System.out.println(file1.getName()); // wb
}
private static void method1() {
File file = new File("C:\\wb\\a.txt");
System.out.println(file.isFile()); // true
System.out.println(file.isDirectory()); // false
}
private static void method2() {
File file = new File("C:\\wb");
System.out.println(file.isFile()); // false
System.out.println(file.isDirectory()); // true
}
private static void method3() {
File file = new File("a.txt");
System.out.println(file.exists()); // false(假设不存在)
}
}
File的高级获取方法:listFiles
File[] listFiles() 返回目录下所有文件和文件夹的File对象数组(包括隐藏文件/文件夹)。
注意事项
| 调用者情况 | 返回值 |
|---|---|
| 调用者是文件 | 返回 null |
| 调用者是空文件夹 | 返回长度为0的数组 |
| 调用者是有内容的文件夹 | 返回包含所有子文件和子文件夹的数组 |
| 调用者不存在或无权限 | 返回 null |
代码演示
// FileDemo6.java
public class FileDemo6 {
public static void main(String[] args) {
File file = new File("D:\\aaa");
File[] files = file.listFiles(); // 获取D盘aaa目录下的所有内容
System.out.println(files.length);
for (File path : files) {
System.out.println(path);
}
}
}
综合练习
项目代码结构
本次博客示例的项目结构如下:
filemodule/
└── src/
└── com/
└── wb/
├── filedemo/
│ ├── FileDemo1.java
│ ├── FileDemo2.java
│ ├── FileDemo3.java
│ ├── FileDemo4.java
│ ├── FileDemo5.java
│ └── FileDemo6.java
└── filetest/
├── Test1.java
├── Test2.java
└── Test3.java
filedemo 包:演示 File 类基本 API 的用法。
filetest 包:综合练习,运用所学知识解决实际问题。
1 ) 练习1:在指定目录中创建文件
需求:在当前模块的 aaa 文件夹下创建一个 a.txt 文件。
关键点:createNewFile 要求父文件夹必须存在,否则会抛出 IOException。
因此需要先判断并创建目录,再创建文件。
// Test1.java
public class Test1 {
public static void main(String[] args) throws IOException {
// 目标:在 module/aaa/ 下创建 a.txt
File file = new File("filemodule\\aaa");
if (!file.exists()) {
// 若aaa文件夹不存在,先创建(mkdirs保证多级创建)
file.mkdirs();
}
// 拼接新文件路径
File newFile = new File(file, "a.txt");
newFile.createNewFile();
}
}
2 ) 练习2:递归删除多级文件夹
需求:删除一个包含子文件和子文件夹的多级文件夹。
思路:
- 进入文件夹,获取所有内部内容的File对象数组。
- 遍历数组:如果是文件则直接删除;如果是文件夹则递归删除。
- 内部清空后,最后删除自身。
递归流程图(假设目录结构为 src 内含 a.txt、b.txt 和 AAA 文件夹,AAA 内含 a.txt 和空文件夹):
对应代码:
// Test2.java
public class Test2 {
public static void main(String[] args) {
File src = new File("C:\\Users\\apple\\Desktop\\src");
deleteDir(src);
}
private static void deleteDir(File src) {
// 1. 进入文件夹,获取所有内容
File[] files = src.listFiles();
// 2. 遍历
for (File file : files) {
if (file.isFile()) {
// 3. 文件直接删除
file.delete();
} else {
// 4. 文件夹:递归删除
deleteDir(file);
}
}
// 最后删除该文件夹自身
src.delete();
}
}
3 ) 练习3:统计文件夹中每种文件出现的次数
需求:统计一个文件夹中,每种文件(.txt, .java, .jpg 等)的数量并打印。
思路:
使用 HashMap<String, Integer> 集合,键为后缀名,值为次数。
利用递归遍历所有子文件夹。
对于每个文件,截取后缀名,更新Map中的计数。
注意:需处理无后缀或特殊文件名的情况,此处仅统计正则分割后长度为2的文件。
// Test3.java
public class Test3 {
public static void main(String[] args) {
File file = new File("filemodule");
HashMap<String, Integer> hm = new HashMap<>();
getCount(hm, file);
System.out.println(hm);
}
private static void getCount(HashMap<String, Integer> hm, File file) {
File[] files = file.listFiles();
for (File f : files) {
if (f.isFile()) {
String fileName = f.getName();
String[] fileNameArr = fileName.split("\\.");
if (fileNameArr.length == 2) {
String fileEndName = fileNameArr[1];
if (hm.containsKey(fileEndName)) {
// 已存在:获取原有次数,+1
Integer count = hm.get(fileEndName);
count++;
hm.put(fileEndName, count);
} else {
// 首次出现:次数记为1
hm.put(fileEndName, 1);
}
}
} else {
// 文件夹:递归
getCount(hm, f);
}
}
}
}
这样,我们便完成了对文件夹内各类文件数量的统计。
总结
通过本篇的学习,你将掌握 File 类的基本使用方法,理解绝对/相对路径、文件的创建与删除、递归操作等核心技能,为后续学习 IO 流打下坚实基础。
238

被折叠的 条评论
为什么被折叠?



