当前位置: 首页 > news >正文

Java 黑马程序员学习笔记(进阶篇22)

1. File 类概述

(1) 作用: 

java.io.File 类用于表示文件或目录的路径(抽象表示,与平台无关),可对文件 / 目录的路径、名称、大小等元数据进行操作,但不能读写文件内容(读写内容需用流)。

(2) 注意
  • File 对象仅代表 “路径” 的抽象描述,不依赖于实际文件 / 目录是否存在。
  • 路径分隔符:Windows 用 \(转义后为 \\),Linux/macOS 用 /;推荐用 File.separator 实现跨平台(如 File.separator + "test.txt")。

2. File 类构造方法

作用:创建 File 对象,绑定一个路径(文件或目录)。

构造方法说明示例
File(String pathname)通过字符串路径创建 File 对象File f = new File("D:\\test.txt");
File(String parent, String child)通过父路径 + 子路径创建(更灵活)File f = new File("D:\\", "test.txt");
File(File parent, String child)通过父 File 对象 + 子路径创建(推荐)File parent = new File("D:\\"); File f = new File(parent, "test.txt");

3. File 类常用方法

(1) 判断功能(路径状态)
方法名返回值说明
exists()boolean判断路径对应的文件 / 目录是否存在
isFile()boolean判断是否为文件(需先确认 exists ())
isDirectory()boolean判断是否为目录(需先确认 exists ())
(2) 获取功能(路径 / 名称 / 大小等)
方法名返回值说明
getAbsolutePath()String获取绝对路径(完整路径)
getPath()String获取构造方法中传入的路径(可能相对)
getName()String获取文件 / 目录的名称(路径最后部分)
length()long获取文件大小(字节数);目录返回 0
lastModifiedlong返回文件的最后修改时间(时间毫秒值)
(3) 创建 / 删除功能
方法名返回值说明
createNewFile()boolean创建文件(若不存在);目录不存在则失败
mkdir()boolean创建单级目录(父目录必须存在)
mkdirs()boolean创建多级目录(父目录不存在则自动创建)
delete()boolean删除文件或空目录(非空目录删不掉)

3. 实战

(1) 带筛选条件的遍历(如只遍历.txt 文件)

使用 listFiles(FileFilter filter) 方法可以筛选特定类型的文件(如只保留.txt文件)。

示例代码:

package demo1;import java.io.File;public class test5 {public static void main(String[] args) {File f = new File("D:\\aaa");File[] arr = f.listFiles();for (File file : arr) {if (file.isFile() && file.getName().endsWith(".txt")) {System.out.println(file);}}}
}

4. 综合练习

(1) 创建多级目录及文件

① 使用File类在当前项目路径下创建多级目录 day25-test\aaa(注意:路径分隔符使用\)。

② 在上述创建的 aaa 目录下,创建一个名为 a.txt 的文件。

③ 根据文件创建的结果(成功或失败),在控制台输出对应的信息:若文件创建成功,输出 “创建成功”;若文件已存在或创建失败,输出 “创建失败”。

④ 程序需处理可能出现的IOException(通过throws声明抛出即可)。

要求:

  • 使用File类的mkdirs()方法创建多级目录。
  • 使用File类的createNewFile()方法创建文件。
  • 类名定义为test1,包名为demo2
package demo2;import java.io.File;
import java.io.IOException;public class test1 {public static void main(String[] args) throws IOException {File file = new File("day25-test\\aaa");file.mkdirs();File src = new File(file,"a.txt");boolean b = src.createNewFile();if(b) {System.out.println("创建成功");} else {System.out.println("创建失败");}}
}
(2) 查找系统中所有.avi 文件

请编写一个 Java 程序,实现以下功能:

① 遍历当前系统的所有根目录(如 Windows 的 C:\、D:\,Linux/macOS 的 / 等)。

② 递归遍历每个根目录下的所有子目录及文件,查找所有扩展名为.avi的文件。

③ 找到.avi文件后,在控制台打印该文件的完整路径。

要求:

  • 使用File.listRoots()方法获取系统所有根目录。
  • 使用递归方式遍历所有层级的目录(通过方法重载实现:一个无参方法用于初始化根目录遍历,一个带File参数的方法用于递归处理目录)。
  • 通过File.listFiles()方法获取目录下的子文件 / 子目录,需判断返回值非空(避免无权限访问的目录导致异常)。
  • 通过File.isFile()判断是否为文件,并通过String.endsWith(".avi")筛选.avi文件。
  • 类名定义为test3,包名为demo2
package demo2;import java.io.File;public class test3 {public static void main(String[] args) {findAVI();}public static void findAVI() {File[] arr = File.listRoots();for (File f : arr) {findAVI(f);}}public static void findAVI(File src) {File[] files = src.listFiles();if(files != null) {for (File file : files) {if(file.isFile()) {String name = file.getName();if(name.endsWith(".avi")) {System.out.println(file);}} else {findAVI(file);}}}}
}
关键逻辑:递归
① 递归的 “起点”

无参方法 findAVI() 是递归的入口:

public static void findAVI() {File[] arr = File.listRoots(); // 获取系统所有根目录(如C:\、D:\)for (File f : arr) {findAVI(f); // 对每个根目录启动递归}
}

这里的根目录(如 C:\)是遍历的起点,我们从最顶层的根目录开始,逐层深入。

② 递归的 “分解步骤”

带参方法 findAVI(File src) 是递归的核心,负责 “分解问题”:

public static void findAVI(File src) {File[] files = src.listFiles(); // 获取当前目录下的所有文件/子目录if(files != null) { for (File file : files) { if(file.isFile()) { // 若当前元素是文件// 检查是否为.avi文件,是则打印if(file.getName().endsWith(".avi")) {System.out.println(file);}} else { // 若当前元素是子目录findAVI(file); // 递归调用:用同样的逻辑处理子目录}}}
}
  • 对于任意一个目录 src,先获取它的直接子元素(文件或子目录);
  • 若子元素是文件:直接检查是否为 .avi(这是 “最小子问题”,无需再递归);
  • 若子元素是子目录:则把这个子目录作为新的 “起点”,调用 findAVI(file) 重复上述过程(即 “自己调用自己处理子问题”)。
③ 递归的 “终止条件”

递归必须有明确的终止条件,否则会陷入无限循环。这里的终止条件是:

  • 当遍历到文件时(file.isFile() == true),不再递归,仅执行 “检查是否为.avi” 的操作;
  • 当目录无权限访问时(files == null),直接结束当前方法,不再继续递归(避免空指针异常)。
(3) 计算目录下所有文件的总大小

请编写一个 Java 程序,实现以下功能:

① 定义一个方法 getLen(File src),用于计算指定目录 src 下所有文件的总大小(单位:字节),包括该目录下所有子目录中的文件。

② 计算逻辑:若 src 目录下的元素是文件,则累加其大小(通过 length() 方法获取);若元素是子目录,则递归调用 getLen 方法计算该子目录的文件总大小,并累加至总和。

③ 在 main 方法中,以 D:\\aaa\\src 为目标目录,调用 getLen 方法计算总大小,并在控制台输出结果。

④ 类名定义为 test5,包名为 demo2

package demo2;import java.io.File;public class test5 {public static void main(String[] args) {File file = new File("D:\\aaa\\src");long len = getLen(file);System.out.println(len);}public static long getLen(File src) {long len = 0;File[] files = src.listFiles();for (File file : files) {if(file.isFile()) {len += file.length();} else {len = len + getLen(file);  // 不太理解}}return len;}
}
关键逻辑:递归是怎么 “深入” 子目录计算的?

我们以刚才的例子(src 包含 a.txt 和 sub 目录,sub 包含 b.txt),一步步看 getLen 方法的执行过程:

① 首先在 main 方法中调用 getLen(new File("D:\\aaa\\src")),此时 src 是 src 目录。
  • 执行 File[] files = src.listFiles(),得到 files 数组(包含 a.txt 和 sub 两个元素)。
② 遍历 files 数组:
  • 第一个元素是 a.txt(文件):执行 if(file.isFile()) { len += file.length(); },此时 len 累加 a.txt 的大小(100 字节),len 变为 100。

  • 第二个元素是 sub(子目录):执行 else { len = len + getLen(file); },这里会递归调用 getLen(sub)(用同样的方法计算 sub 目录的总大小)。

③ 进入递归调用 getLen(sub)sub 是子目录):
  • 执行 File[] files = sub.listFiles(),得到 files 数组(包含 b.txt 一个元素)。
  • 遍历 files 数组,元素是 b.txt(文件):执行 len += file.length(),此时 getLen(sub) 方法中的 len 累加 b.txt 的大小(200 字节),len 变为 200。
  • 遍历结束,getLen(sub) 返回 200。
④ 回到最初的 getLen(src) 方法:
  • 刚才递归调用返回了 200,所以执行 len = 100 + 200len 变为 300。
  • 遍历结束,getLen(src) 返回 300,最终 main 方法输出 300。
(4) 统计目录及子目录中文件后缀名的数量

请编写一个 Java 程序,实现以下功能:

① 统计指定目录(包括所有子目录)下所有文件的后缀名数量(例如:.txt 文件有 3 个,.jpg 文件有 5 个等)。

② 具体要求:

  • 使用 HashMap<String, Integer> 存储统计结果,键为后缀名(如 txtjpg),值为该后缀名的文件总数。
  • 对于无后缀名的文件(如 readme),不进行统计。
  • 对于多后缀名的文件(如 image.tar.gz),以后缀中最后一个 . 后的部分作为统计依据(即统计为 gz)。

③ 在 main 方法中,以 D:\\aaa\\src 为目标目录,调用统计方法获取结果并打印。

④ 类名定义为 test4,包名为 demo2

package demo2;import java.io.File;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;public class test4 {public static void main(String[] args) {File file = new File("D:\\aaa\\src");HashMap<String, Integer> hm = getCount(file);System.out.println(hm);}public static HashMap<String, Integer> getCount(File src) {HashMap<String, Integer> hm = new HashMap<String, Integer>();File[] files = src.listFiles();for (File file : files) {if(file.isFile()) {String name = file.getName();String[] arr = name.split("\\.");if(arr.length >= 2) {String endName = arr[arr.length - 1];  // 不太理解if(hm.containsKey(endName)) {hm.put(endName, hm.get(endName) + 1);} else {hm.put(endName, 1);  // 不太理解}}} else {HashMap<String, Integer> sonMap = getCount(file);Set<Map.Entry<String, Integer>> entries = sonMap.entrySet();for (Map.Entry<String, Integer> entry : entries) {String key = entry.getKey();int value = entry.getValue();if(hm.containsKey(key)) {hm.put(key, hm.get(key) + value);} else {hm.put(key, value);}}}}return hm;}
}
关键逻辑 1:提取后缀名:String endName = arr[arr.length - 1];
① 作用:

从文件名中提取后缀名,尤其是处理多后缀名的文件(如 a.tar.gz)。

② 示例:
  • 文件名 test.txt → 用 split("\\.") 分割(. 是正则特殊字符,需转义为 \\.)→ 得到数组 ["test", "txt"] → arr.length - 1 = 1 → endName = "txt"
  • 文件名 image.tar.gz → 分割后数组 ["image", "tar", "gz"] → arr.length - 1 = 2 → endName = "gz"(取最后一个 . 后的部分,符合实际后缀习惯)。

③ if(arr.length >= 2):过滤无后缀名的文件(如 readme 分割后数组长度为 1,不满足条件,不统计)。

关键逻辑 2: 初始化统计数量:hm.put(endName, 1);
① 作用:

当某种后缀名第一次出现时,在 HashMap 中记录 “该后缀名的文件数量为 1”。

② 逻辑:
  • hm.containsKey(endName):判断当前 HashMap 中是否已有该后缀名的记录。
    • 若已有(如之前统计过 txt 文件):则更新数量(hm.put(endName, hm.get(endName) + 1),例如从 2 个变为 3 个)。
    • 若没有(第一次遇到 txt 文件):则添加新记录(键为 txt,值为 1)。
http://www.dtcms.com/a/550874.html

相关文章:

  • 网页制作用哪个软件宁波seo的公司联系方式
  • 如何理解不同行业AI决策系统的功能差异?
  • 长沙英文网站建设公司郑州大型网站公司
  • 建设部网站村镇建设口碑营销的产品
  • 网站建设网站模版广东省建设工程交易中心
  • 深圳网站建设培训班本科自考有哪些科目
  • RHEL 9.6 从源码安装 Open vSwitch 完整指南
  • 域名跟空间都有了怎么做网站网站的思维导图怎么做
  • 高端建站用什么软件菏泽 做网站 多少钱
  • 网站导航页设计标识设计公司排名
  • 【符号论】群的概念与五行关系的循环群结构
  • 宜兴网站建设价格信息做海报的素材那个网站比较好
  • 网站开发用到的技术上海网站建设上海
  • 昆山高端网站建设咨询设计公司职位
  • 你问GeeLark答 QA 第8章
  • 南京360推广 网站建设网页视频加速器
  • 有谁知道网站优化怎么做南宁网站建设信息推荐
  • 永川区网站建设名词解释搜索引擎优化
  • 点云深度学习:KPFCNN(Kernel Point Convolutional Neural Network)
  • Rust:类型 impl
  • STM32项目分享:避障小车设计
  • 从密集到稀疏:InfLLM-V2 如何实现零参数开销的长文本高效处理
  • 网站推广平台排行如何免费建立官方网站
  • 基于MATLAB的Copula函数实现合集
  • p2p贷款网站建设建设网站需要的人员及资金
  • 佛山市网站建设分站哪家好开发公司物业移交物业协议
  • wordpress 网站导航龙岩食品有限公司
  • 有网站做点什么好wordpress多媒体插件
  • 网站建设得缺点自媒体营销推广
  • 李红波先生与EDT过滤器(替代ERF1150X FILTER)的故事