Java 文件操作 和 IO(5)-- 综合案例练习 -- 示例三

article/2025/6/7 14:15:32

文章目录

  • 题目描述:扫描指定目录,并找到文件名称或文件内容中包含指定字符的所有普通文件(不包含目录)
  • 结果案例演示:
  • 设计思路:
    • 总体的思路:
    • 使用代码,分步实现
      • 1. 准备工作(输入目录路径,创建File对象,判断,输入关键字)
      • 2. 开始遍历目录
      • 3. 实现scanDir方法
        • 3.1 获取到目录中的所有文件(File对象),同时,判断该目录是否为一个空目录
        • 3.2 遍历当前目录中的内容,然后判断当前文件时普通文件还是目录,两种情况:
          • 3.2.1 如果是普通文件,则调用dealFile方法,进行文件名或文件内容的判定
          • 3.2.2 如果是目录,则递归调用本方法
      • 4. 实现dealFile方法
        • 4.1 判定文件名是否包含关键字
        • 4.2 判定文件内容是否包含关键字
          • 4.2.1 设置 StringBuilder,把读到的字符内容拼接到 stringBuilder
          • 4.2.2 由于 关键字 是字符串,读取文件内容使用 字符流 的方式来进行处理
          • 4.2.3 循环读取,且一次读取多个字节,所以需要创建一个字符数组
          • 4.2.4 使用append( ),进行追加操作,读到多少,追加多少
          • 4.2.5 拼接读取完毕后,stringBuilder 就是文件内容中的字符,判断 stringBuilder 是否包含关键字,有两种判断方式:
  • 完整代码:
  • 总结:

题目描述:扫描指定目录,并找到文件名称或文件内容中包含指定字符的所有普通文件(不包含目录)

本题还是进行目录的搜索,和 扫描指定目录,并找到名称中包含自定字符的所有普通文件(不包含目录),并且后续询问用户是否要删除该文件,这篇博客介绍的程序差不多,但是本次不是删除而是要加上一个文件内容读取的步骤。

本次的程序,不仅要找到文件名称中包含指定字符的普通文件,还要找到文件内容中包含指定字符的普通文件
例如:关键词为 test,那么这个程序可以找到文件名中有 test 这个字符的文件,也可以找到文件内容有 test 这个字符的文件。

结果案例演示:

以下的演示,我统一以我本人当前该程序的项目路径为例:
E:\code\gitee\JAVA代码\java-code-\java_File_IO_11.28

关键词,以 test 为例子。
运行结果:
在这里插入图片描述

设计思路:

总体的思路:

准备工作:
第一步:我们需要让用户输入一个指定的目录,确定搜索的是哪个目录,搜索该目录里面的文件。
第二步:根据用户输入的目录路径,创建 File对象,同时,判定用户输入的目录路径,是否为一个目录,如果不是,则不进行搜索,直接 return 结束程序。
第三步:如果用户输入的目录路径是一个目录,就让用户输入要文件名或文件内容包含的关键字
以上步骤没有问题以后,我们就开始遍历目录了。

遍历目录:
遍历目录的代码,我们写到一个方法里面,scanDir方法,传入两个变量

  1. 第一个变量:根据目录的路径所创建的 File对象(我代码中的 rootfile),
  2. 第二个变量:要删除的文件中,文件名包含的关键字(我代码中的 keyword)。

scanDir方法 遍历目录内容的步骤

  1. 获取目录中的所有文件(File对象),使用 File数组 进行接收,同时,判断这个数组的引用是否为空(null),进而判断该目录是否为一个空目录(即目录什么文件都没有,listFiles()就会返回 null)。
    如果是空的,直接返回,不用进行遍历了。
  2. 目录内容不为空后,遍历当前目录中的内容(File数组),然后判断当前文件是 普通文件 还是 目录,两种情况:
    2.1 如果是 普通文件,则 调用dealFile方法,进行判定是否存在关键字
    2.2 如果是 目录,则递归调用本方法(scanDir方法)

dealFile方法文件名文件内容进行判定,是否包含关键字(keyword):

  1. 判定文件名是否包含关键字,如果文件名包含关键字,就打印出该文件的绝对路径,并且 return,结束该方法,如果文件名不包含关键字,则判定文件内容是否包含关键字
  2. 判定文件内容是否包含关键字:
    读取到文件中的内容,用 StringBuilder 类拼接成一个字符串,再去用关键字和这个字符串进行判断

2.1 由于 关键字 是字符串,所以我们这里就用字符流的方式来进行处理

2.2 此处是采用一次性读取多个字符,所以需要创建一个 字符数组(char[ ]),接收读取到的字符,大小任意

2.3 实例化 StringBuilder类 的对象 stringBuilder,把读到的字符内容拼接到 stringBuilder,进行追加写操作,且读到多少,追加多少stringBuilder.append(chars,0,n);,0 表示从char[ ]数组的起始下标开始追加,n 表示此次读取到的字符数。

2.4 判断 stringBuilder是否包含关键字,列举两种判断方式

  • 第一种:使用 if (stringBuilder.indexOf(keyword) >= 0),判断思路:从 stringBuilder 的0下标开始找,找到 keyword表示的关键字 后,返回其 字符串的首字符下标。只要找到返回的字符串的首字符下标,**必然是 大于等于0(>=0)**的数字,如果没找到,返回 -1
  • 第二种:使用 stringBuilder.toString().contains(keyword),判断思路:使用 toString( )方法,输出为字符串后,再用 contains( )方法,判断是否包含关键字

关于 indexOf( )方法,不熟悉的,可以查看 Java的String类(上),这篇博客中 2.4.2 标题的内容,里面清楚的介绍了 indexOf( )方法。

这道题目,相比于示例一那道题目,区别在于,需要读取文件中的内容,并且拼接到字符串中,再去判断,字符串中是否包含关键字。

使用代码,分步实现

1. 准备工作(输入目录路径,创建File对象,判断,输入关键字)

//        准备工作:
//        第一步:输入指定的目录路径Scanner scanner = new Scanner(System.in);System.out.println("输入你要搜索的目录的路径(绝对 or 相对):");String rootDir = scanner.next();//        第二步:根据输入的目录路径,创建File文件File rootfile = new File(rootDir);
//        其次,判断这个文件是否为一个目录,不是目录,则退出程序if (!rootfile.isDirectory()){System.out.println("你输入的路径不是一个目录!");return;}//        第三步:输入关键字System.out.println("请输入目录中的文件的文件名所包含的关键字:");String keyword = scanner.next();

2. 开始遍历目录

scanDir(rootfile,keyword);

3. 实现scanDir方法

private static void scanDir(File rootfile, String keyword) {}
3.1 获取到目录中的所有文件(File对象),同时,判断该目录是否为一个空目录
//        第一步:使用listFiles()获取到目录中的各个文件File[] files = rootfile.listFiles();
//        判断目录是否为空目录if (files == null) {return;}
3.2 遍历当前目录中的内容,然后判断当前文件时普通文件还是目录,两种情况:
//        第二步:对每个文件进行判定,判断是不是目录for (File file:files) {if (file.isFile()) {
//                如果这个文件是一个普通文件,进行文件名和文件内容的判定dealFile(file, keyword);} else {
//                如果不是文件,就应该是目录,使用递归的方式,深度搜索scanDir(file,keyword);}}
3.2.1 如果是普通文件,则调用dealFile方法,进行文件名或文件内容的判定
//1.如果这个文件是一个普通文件,调用dealFile方法,进行文件名和文件内容的判定
dealFile(file, keyword);
3.2.2 如果是目录,则递归调用本方法
//2.如果是目录,则递归调用本方法
scanDir(file,keyword);

4. 实现dealFile方法

private static void dealFile(File file, String keyword) {}
4.1 判定文件名是否包含关键字
//        1.判定文件名是否包含关键字if (file.getName().contains(keyword)) {System.out.println("文件名包含关键字:" + file.getAbsolutePath());return;}
4.2 判定文件内容是否包含关键字
//        2.判定文件内容是否包含关键字
//        设置 StringBuilder,把读到的字符内容拼接到 stringBuilderStringBuilder stringBuilder = new StringBuilder();
//        读取文件内容的操作
//        由于keyword是字符串,就按照字符流的方式来进行处理try(Reader reader = new FileReader(file)) {while (true) {char[] chars = new char[1024];int n = reader.read(chars);
//                判断是否读取完毕if (n == -1) {break;}
//                把读到的每一段内容,都进行一个追加操作
//                读到多少,追加多少stringBuilder.append(chars,0,n);}//            判断 StringBuilder 是否包含关键字//            第一种判断方式:
//            if (stringBuilder.toString().contains(keyword)) {
                包含关键字
//                System.out.println("文件内容包含关键字:" + file.getAbsolutePath());
//            }//            第二种判断方式:if (stringBuilder.indexOf(keyword) >= 0) {
//                包含关键字System.out.println("文件内容包含关键字:" + file.getAbsolutePath());}} catch (IOException e) {throw new RuntimeException(e);}
4.2.1 设置 StringBuilder,把读到的字符内容拼接到 stringBuilder
//        设置 StringBuilder,把读到的字符内容拼接到 stringBuilderStringBuilder stringBuilder = new StringBuilder();
4.2.2 由于 关键字 是字符串,读取文件内容使用 字符流 的方式来进行处理
//        由于keyword是字符串,就按照字符流的方式来进行处理try(Reader reader = new FileReader(file)) {
//        读取文件的操作....} catch (IOException e) {throw new RuntimeException(e);}
4.2.3 循环读取,且一次读取多个字节,所以需要创建一个字符数组
            while (true) {char[] chars = new char[1024];int n = reader.read(chars);
//                判断是否读取完毕if (n == -1) {break;}}
4.2.4 使用append( ),进行追加操作,读到多少,追加多少
//                把读到的每一段内容,都进行一个追加操作
//                读到多少,追加多少stringBuilder.append(chars,0,n);
4.2.5 拼接读取完毕后,stringBuilder 就是文件内容中的字符,判断 stringBuilder 是否包含关键字,有两种判断方式:
  1. 第一种:使用 if (stringBuilder.indexOf(keyword) >= 0),判断思路:从stringBuilder 的0下标开始找找到 keyword表示的关键字 后,返回其 字符串的首字符下标。只要找到,返回的字符串的首字符下标必然是 大于等于0(>=0)的数字,如果没找到,返回 -1
//            第一种判断方式:if (stringBuilder.toString().contains(keyword)) {
//                包含关键字System.out.println("文件内容包含关键字:" + file.getAbsolutePath());}
  1. 第二种:使用 stringBuilder.toString().contains(keyword),判断思路:使用 toString( )方法,输出为字符串后,再用 contains( )方法,判断是否包含关键字
//            第二种判断方式:if (stringBuilder.indexOf(keyword) >= 0) {
//                包含关键字System.out.println("文件内容包含关键字:" + file.getAbsolutePath());}

完整代码:

import java.io.*;
import java.util.Scanner;public class demo4 {public static void main(String[] args) {
//        准备工作:
//        第一步:输入指定的目录路径Scanner scanner = new Scanner(System.in);System.out.println("输入你要搜索的目录的路径(绝对 or 相对):");String rootDir = scanner.next();//        第二步:根据输入的目录路径,创建File文件File rootfile = new File(rootDir);
//        其次,判断这个文件是否为一个目录,不是目录,则退出程序if (!rootfile.isDirectory()){System.out.println("你输入的路径不是一个目录!");return;}//        第三步:输入关键字System.out.println("请输入目录中的文件的文件名所包含的关键字:");String keyword = scanner.next();scanDir(rootfile,keyword);}private static void scanDir(File rootfile, String keyword) {
//        第一步:使用listFiles()获取到目录中的各个文件File[] files = rootfile.listFiles();//        第二步:对每个文件进行判定,判断是不是空目录for (File file:files) {if (file.isFile()){
//                如果这个文件是一个普通文件,就进行删除判定dealFile(file, keyword);} else {
//                如果不是文件,就应该是目录,使用递归的方式,深度搜索scanDir(file,keyword);}}}private static void dealFile(File file, String keyword) {
//        1.判定文件名是否包含关键字if (file.getName().contains(keyword)) {System.out.println("文件名包含关键字:" + file.getAbsolutePath());return;}
//        2.判定文件内容是否包含关键字
//        设置 StringBuilder,把读到的字符内容拼接到StringBuilderStringBuilder stringBuilder = new StringBuilder();
//        读取文件内容的操作
//        由于keyword是字符串,就按照字符流的方式来进行处理try(Reader reader = new FileReader(file)) {while (true) {char[] chars = new char[1024];int n = reader.read(chars);
//                判断是否读取完毕if (n == -1) {break;}
//                把读到的每一段内容,都进行一个追加操作
//                读到多少,追加多少stringBuilder.append(chars,0,n);}//            判断 StringBuilder 是否包含关键字//            第一种判断方式:
//            if (stringBuilder.toString().contains(keyword)) {
                包含关键字
//                System.out.println("文件内容包含关键字:" + file.getAbsolutePath());
//            }//            第二种判断方式:if (stringBuilder.indexOf(keyword) >= 0) {
//                包含关键字System.out.println("文件内容包含关键字:" + file.getAbsolutePath());}} catch (IOException e) {throw new RuntimeException(e);}return;}
}

总结:

这一个代码,对于搜索文件,总体来说,是一个比较低效的方法。

因为我们这个查找过程,我们需要针对所有的文件的文件名和文件内容进行遍历,整体的一个遍历的开销,如果文件多的话,这种开销是比较大的。

如果,你的是整个 C盘(算是一个很大的目录),那么,搜索的时间就很久了,你可以自己试试。

总体来说,是一个比较慢的方案

更高效的方案,就是“搜索引擎”。例如:百度,搜狗等。
搜索引擎做的事情,就是在海量的文件当中,找到哪些文件的内容包含了关键字,而且,还要识别出哪些文件的相关性更高,排到前面。
搜索引擎,会有一系列的优化,提高搜索的效率,最核心的技术点,叫做:“倒排索引”。

至于 “倒排索引”,是什么,原理是什么,这里就不展开说了,有兴趣的,可以去 B站,搜索视频看一下。

最后,如果这篇博客有帮到你的,请你点点赞,有写错了,写的不好的,欢迎评论指出,谢谢!


http://www.hkcw.cn/article/qwFWnFBVYv.shtml

相关文章

微深节能 筒仓卸料小车远程智能控制系统 格雷母线

微深节能筒仓卸料小车远程智能控制系统——格雷母线高精度定位解决方案 在现代化筒仓物料管理中,卸料小车的精准定位与远程控制是提升效率、保障安全的关键。武汉市微深节能科技有限公司推出的格雷母线高精度位移测量系统,为筒仓卸料小车提供远程智能控…

股票指数期货的变动与股票价格指数的关系是什么?

很多小伙伴刚接触金融投资的时候,常常会听到“股票指数期货”和“股票价格指数”这两个词,但搞不清楚它们之间的关系。今天,我就给大家讲讲,这两个东西到底是什么关系。 一、股票价格指数是个什么? 股票价格指数&…

2025LitCTF re wp复现

LitCTF2025 wp&&复现 easy_rc4 魔改RC4,直接在异或处下条件断点,动调获取密钥流 FeatureExtraction 定位到main 前面都是一些初始化函数以及把输入的char型字符串转成int型数据 关键加密在sub_401722(Block, des) 加密逻辑就是 unsigned in…

Lovable + Cursor:零基础搭建专业应用的秘密武器

🚀 Lovable + Cursor:零基础搭建专业应用的秘密武器 为什么你需要这个工作流? 想象一下这样的场景:你用Lovable快速搭建了一个漂亮的网页原型,但当你想要添加更复杂的功能时,却发现自己被限制住了。或者你在Cursor里写代码很顺手,但每次从零开始设计界面都让你头疼不…

ARM GIC V3概述

中断类型 locality- specific peripheral interrupt(LPI):LPI是一个有针对性的外设中断,通过affinity路由到特定的PE。 为非安全group1中断边沿触发可以通过its进行路由没有active状态,所以不需要明确的停用操作LPI总…

Docker部署与应用、指令

部署 【Docker】在 Ubuntu 22.04 以下版本上安装 Docker 的详细指南_ubuntu 安装docker-CSDN博客 应用 使用指定镜像创建并运行一个新容器 --name,指定容器名称 -d 代表后台运行 nginx 代表容器镜像名 docker ps 查看运行的容器 -a 查看…

内网横向之RDP缓存利用

RDP(远程桌面协议)在连接过程中会缓存凭据,尤其是在启用了 "保存密码" 或 "凭据管理器" 功能时。这个缓存的凭据通常是用于自动填充和简化后续连接的过程。凭据一般包含了用户的用户名和密码信息,或者是经过加…

从计量到通信,DJSF1352-D为快充桩系统提供了怎样的解决方案?

摘要 随着新能源汽车保有量的不断攀升,直流充电桩成为城市交通与能源基础设施的重要组成部分。电能计量作为充电桩运营、结算和安全管理的核心环节,对计量设备提出了更高的要求。安科瑞DJSF1352D导轨式直流电能表,凭借高精度、高稳定性和通信…

0518蚂蚁暑期实习上机考试题1:数组操作

题目 小红认为一个长度为 n 的数组 a 是好的,当且仅当对于任意的 i ,均满足相等,其中数组下标 i 从 1 开始,小红每次可以对一个数加 1 或者减 1 ,求把给定的数组变成好数组的最少操作次数。 输入描述:第一…

深入对比主流Java Web服务器与框架

目录 一、核心技术对比概览 二、深度解析与应用场景 1. Apache Tomcat - 企业级标准容器 2. Netty - 高性能网络编程框架 3. Undertow - 轻量级嵌入式服务器 4. Vert.x - 响应式应用框架 5. Play Framework - 全栈Web框架 三、性能基准测试对比(参考数据&am…

晶台光耦在手机PD快充上的应用

光耦(光电隔离器)作为关键电子元件,在手机PD快充中扮演信号隔离与传输的“安全卫士”。其通过光信号实现电气隔离,保护手机电路免受高电压损害,同时支持实时信号反馈,优化充电效率。 晶台品牌推出KL817、KL…

EscapeX:去中心化游戏,开启极限娱乐新体验

VEX 平台推出全新去中心化游戏 EscapeX(数字逃脫),创新性地将大逃杀玩法与区块链技术相融合。用户不仅能畅享紧张刺激的解谜过程,更能在去中心化、公正透明的环境中参与游戏。EscapeX 的上线,为 VEX 生态注入全新活力&…

服务端定时器的学习(一)

一、定时器 1、定时器是什么? 定时器不仅存在于硬件领域,在软件层面(客户端、网页和服务端)也普遍应用,核心功能都是高效管理大量延时任务。不同应用场景下,其实现方式和使用方法有所差异。 2、定时器解…

Axure形状类组件图标库(共8套)

点击下载《月下倚楼图标库(形状组件)》 原型效果:https://axhub.im/ax9/02043f78e1b4386f/#g1 摘要 本图标库集锦精心汇集了8套专为Axure设计的形状类图标资源,旨在为产品经理、UI/UX设计师以及开发人员提供丰富多样的设计素材,提升原型设计…

CET6 仔细阅读 24年12月第一套-C1 大脑这一块

文章 There are hundreds of personality quizzes online that assert they can ascertain whether the right or left half of your brain is dominant. Left-brained people are supposedly logical and excel at language and math while right- brained people are more i…

【JavaWeb】SpringBoot原理

1 配置优先级 在前面,已经学习了SpringBoot项目当中支持的三类配置文件: application.properties application.yml application.yaml 在SpringBoot项目当中,我们要想配置一个属性,通过这三种方式当中的任意一种来配置都可以&a…

硬件工程师笔记——555定时器应用Multisim电路仿真实验汇总

目录 一 555定时器基础知识 二、引脚功能 三、工作模式 1. 单稳态模式: 2. 双稳态模式(需要外部电路辅助): 3. 无稳态模式(多谐振荡器): 4. 可控脉冲宽度调制(PWM&#xff09…

基于springboot的图书管理系统的设计与实现

其他源码获取可以看首页:代码老y 个人简介:专注于毕业设计项目定制开发:springbootvue系统,Java微信小程序,javaSSM系统等技术开发,并提供远程调试部署、代码讲解、文档指导、ppt制作等技术指导。源码获取&…

一个html实现数据库自定义查询

使用场景 应用上线后甲方频繁的找开发查询数据库数据,且没有固定的查询规律,产品经理也没有规划报表需求。 实现方案 后端开放自定义sql查询,屏蔽所有数据库的高危操作,将常用查询的sql放在一个html中的js中直接查询&#xff0…

[特殊字符] Unity UI 性能优化终极指南 — ScrollRect篇

ScrollRect ManualScrollRect API 我参考了官方最新文档(基于UGUI 3.0包),加上实际性能测试经验,直接给你梳理: 🎯 Unity UI 性能优化终极指南 — ScrollRect篇 🧩 什么是 ScrollRect&#xff…